• 《编程珠玑》阅读小记(4) — 编写正确的程序


    本章简述

    本章的主题是编写正确的程序,以一个二分搜索算法引入。

    关于二分搜索

    二分搜索的关键思想是如果t在x[0..n-1]中,那么它就一定存在于x的某个特定范围之内。该程序最重要的部分是大括号内的循环不变式,也就是关于程序状态的断言。
    代码的开发是自上而下进行的(从一般思想开始,将其完善为独立的代码行),该正确性分析则是自下而上进行的,从每个独立的代码行开始,检查它们是如何协同运作并解决问题的。

    关于循环是程序中比较重要的部分,关于其正确性的讨论分为3个部分,每个部分都与循环不变式密切相关。

    • 初始化,循环初始化执行的时候不变式为真
    • 保持,如果在某次迭代开始的时候以及循环体执行的时候,不变式都为真,那么,循环体执行完毕的时候不变式依然为真
    • 终止,循环能够终止并且可以得到期望的结果

    原理

    本章内容展示的程序验证的诸多优势:问题很重要;需要认真编写代码;程序的开发需要遵循验证思想;可以使用一般性的工具进行程序的正确性分析。

    • 断言。输入、程序变量和输出之间的关系勾勒出了程序的“状态”,断言使得程序员可以准确的阐述这些关系。
    • 顺序控制结构。控制程序的最简单的结构莫过于采用“执行这条语句然后执行下一条语句”的形式。
    • 选择控制结构
    • 迭代控制结构
    • 函数

    总结:本章介绍了编写正确的程序的一小部分技术,编写简单的代码是得到正确程序的关键。

    习题分析总结

    1 . 添加边界控制条件0 <= l <= n -1<= u

    /************************************************************************/
    /*
    * 《编程珠玑》第四章 编写正确的程序
    * 习题4.6
    * 2.把t在数组中第一次出现的位置返回给p
    */
    /************************************************************************/
    
    #include <iostream>
    #include <cstdlib>
    
    using namespace std;
    
    //采用递归的形式实现二分搜索
    int binarySearch(int *arr, int left, int right, const int &elem)
    {
        if (left > right)
            return -1;
        int middle = (left + right) / 2;
    
        if (arr[middle] == elem)
            return middle;
        else if (arr[middle] < elem)
        {
            left = middle + 1;
            return binarySearch(arr, left, right, elem);
        }
        else{
            right = middle - 1;
            return binarySearch(arr, left, right, elem);
        }
    }
    
    const int N = 12;
    
    int main()
    {
        int arr[N] = { 1, 2, 3, 6, 6, 6, 6, 7, 8, 9, 10, 12 };
        int t, pos;
        cin >> t;
    
        pos = binarySearch(arr, 0, N - 1, t);
    
        if (pos == -1)
            cout << "The value is not exist." << endl;
    
        while (pos >= 0 && arr[pos] == t)
        {
            pos--;
        }
    
        cout << "The position of value " << t << " is " << pos+1 << endl;
    
        system("pause");
    
        return 0;
    }

    3 . 给出递归形式以及迭代形式的二分搜索算法实现。

    /************************************************************************/
    /*
    * 《编程珠玑》第四章 编写正确的程序
    * 习题4.6
    * 3.对比分析递归实现的二分搜索和迭代实现的二分搜索。
    */
    /************************************************************************/
    
    #include <iostream>
    #include <cstdlib>
    
    using namespace std;
    
    //采用递归的形式实现二分搜索
    //int binarySearch(int *arr, int left, int right, const int &elem)
    //{
    //  if (left > right)
    //      return -1;
    //  int middle = (left + right) / 2;
    //
    //  if (arr[middle] == elem)
    //      return middle;
    //  else if (arr[middle] < elem)
    //  {
    //      left = middle + 1;
    //      return binarySearch(arr, left, right, elem);
    //  }
    //  else{
    //      right = middle - 1;
    //      return binarySearch(arr, left, right, elem);
    //  }
    //}
    
    //采用迭代的形式实现二分搜索
    int binarySearch(int *arr, int left, int right, const int &elem)
    {
        if (left > right)
            return -1;
    
        while ( left < right)
        {
            int middle = (left + right) / 2;
    
            if (arr[middle] == elem)
                return middle;
            else if (arr[middle] < elem)
            {
                left = middle + 1;
            }
            else{
                right = middle - 1;
            }
        }
    
    }
    
    const int N = 12;
    
    int main()
    {
        int arr[N] = { 1, 2, 3, 6, 6, 6, 6, 7, 8, 9, 10, 12 };
        int t, pos;
        cin >> t;
    
        pos = binarySearch(arr, 0, N - 1, t);
    
        if (pos == -1)
            cout << "The vlue is not exist." << endl;
    
    
        cout << "The position of value " << t << " is " << pos << endl;
    
        system("pause");
    
        return 0;
    }

    注释部分采用递归形式实现该算法,下面部分采用迭代形式实现该算法。

    5 . 对于下面这个函数,在输入x为正整数时能够终止的。

    while(x != 1)  do
        if even(x)
            x = x/2
        else
            x = 3*x + 1

    分析:even(x)函数返回>=x的最接近整数 , 输入x后,有限次执行if条件语句,直至 x=0 , 然后执行else语句使得x=1 , 下一次while判断,便退出循环。

    9 . 此题给出几个简单的程序片段,都是可以正确退出循环的。

  • 相关阅读:
    oracle 判断字符串是否包含指定内容
    java 如何使用多线程调用类的静态方法?
    oracle 快速复制表结构、表数据
    oracle 清空表数据的2种方式及速度比较
    一、Instrument之Core Animation工具
    net登录积分(每天登录积分仅仅能加一次) 时间的比較
    正规方程 Normal Equation
    笑谈贝叶斯网络(干货)上
    SQL SERVER 面试题
    好的创始人想要改变世界,最好的创始人还要不放弃——扎克伯格清华中文演讲
  • 原文地址:https://www.cnblogs.com/shine-yr/p/5214949.html
Copyright © 2020-2023  润新知