小小程序媛  
得之坦然,失之淡然,顺其自然,争其必然

本章简述

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

关于二分搜索

二分搜索的关键思想是如果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 . 此题给出几个简单的程序片段,都是可以正确退出循环的。

posted on 2015-06-08 16:06  Coding菌  阅读(156)  评论(0编辑  收藏  举报