“仅有10%的专业程序员能把这个小程序写的完全正确”

MPU 2002-11-16 04:36:39
《程序设计语言5:概念和机构》 裘宗燕 译

书中的一段原话:
例3.4 Bently【1986】要求超过100个专业程序员把下面这段有关二分法的简要描述“写成一个程序,语言由他们自己选择.............
他报告说,“我感到非常惊讶,给了他们充足的时间,仅有10%的专业程序员能把这个小程序写的完全正确”。

我们要确定在一个已经排好序的数组X[1...N]中是否包含元素T。二分法解决问题的方法是维持数组中可能包含T的区域的踪迹(如果元素T确实在数组中的某处)。在开始的区域就是整个数组,通过将元素T与数组的中间元素比较可以缩小范围,丢掉数组的一半。这个过程一直继续T被找到,或者是T可能存在的范围变空。

Berntley提出了如下建议:“绝大多数程序员都认为,只要手头上有了上面这段有
关二分法的描述,写出代码是一件很容易得事。然而他们错了。如果你现在就把这篇文章放在一边,亲自动手写代码试一试。你就会相信这一点。”


我是初学者在“亲自动手写代码试一试”之后我深深的“相信这一点”
在《C++ Primer》中找到一个二分查找的函数:
但我觉得它不“完全正确”。
非完全二分查找,有没有高手帮我写一个。。
谢了!!!!!!!!!!



#include<iostream>
#include<vector>

using namespace std;

int Numsear(vector<int>vec ,int val);
const int notfound = -1;
int main(int argc, char *argv[])
{
vector<int>num(50);
int value;
int size;

cout<<"Enter to size: "<<endl;
cin>>size;
cout<<"Enter to value: "<<endl;
cin>>value;

for(int n=0; n<size; ++n)
{
num[n] = n;
//cout<<num[n]<<endl;
}

if( Numsear(num,value) < 0 )
{
cout<<"The number notfound!"<<endl;
}
else
{
cout<<"The number found!"<<endl;
cout<<Numsear(num,value)<<endl;
}


return 0;
}
////////////////////////////////////////////////////
int Numsear(vector<int>vec,int val)
{

int low =0;
int high = vec.size() - 1;

while( low <= high )
{
int mid = ( low + high ) /2;
if( val == vec[mid] )
return mid;
if( val < vec[mid] )
{
high = mid -1;
}
else {
low = mid + 1;
}
}

return notfound;
}


...全文
76 52 打赏 收藏 转发到动态 举报
写回复
用AI写文章
52 条回复
切换为时间正序
请发表友善的回复…
发表回复
javalzn 2010-06-07
  • 打赏
  • 举报
回复
我觉得自己算是个专业程序员吧,试了一下,3个小时,完全写对,C# 控制台程序。
大家最好试一试。
fujei1981081 2002-11-20
  • 打赏
  • 举报
回复
在短时间内考虑完全的确有点困难
wwwwbb78 2002-11-20
  • 打赏
  • 举报
回复
to:ecivilian(抽象青年)
没考虑到。
Bandry 2002-11-19
  • 打赏
  • 举报
回复
完全正确是什么概念?我想应该根据具体的工作来定义吧,如果给定你一个具体的数组之类数据,让你编写一个二分法来查找某个数据,我想大部分程序员都应该没有问题。这样笼统的说“完全正确”,我想几个小时大家连这个意思都不会明了,如何编程序啊。如果有了具体的概念,那么我们就好做了,这样说“完全正确”只是糊弄我们!大家都学过数据结构,应该知道什么叫“正确的程序”吧,那是要根据实际情况来定义的,没有这种所谓的“完全正确”的程序。我想如果有人再让你写这样的程序,我们可以说“不”!
至于向我们这样提问的人,我们可以对他(她)说“SB”!
vanhui 2002-11-19
  • 打赏
  • 举报
回复
没有完全理解大家对二分法的看法,我学过C的数据结构,单单对于一个简单实例而言,二分法是比较好理解的,应该说就如文字描述的那样非常平淡,至于临时发挥要写的正确确实是有难度的,因为程序员也总是会犯错误的。
个人没有理解的是什么叫完全二分法的查找,需要面向对象进行设计吗?假如要求面向对象的话确实不是一个小程序员能一下子办到的。
freemandan 2002-11-19
  • 打赏
  • 举报
回复
知道算法,也难以写出来,太难了,数组足够大就够麻烦的了。
AceVC 2002-11-19
  • 打赏
  • 举报
回复
TO:langziji(浪子)
if(data[size/2]==value) return base+size/2-1;
//这句中data[size/2]如果size=9 ,就会有问题
我D意思不是说你写错了,如果你D程序+一个对size的判断就应该OK了
TO:gbt()
pdss的
btm=0;top=size-1;cen=btm/2; //应该是笔误,看看他的算法就行,呵呵
wwwwbb78 2002-11-19
  • 打赏
  • 举报
回复

//---------------------------------------------------------------------------
/*清高手帮我看看有什么问题 */

/*这有什么难的,我8:25开始做,8:34写完查找函数,8:45测试完,在测试时改正了一个错误
即如果只有两个元素,就要直接比较。
总费时20Min
CBC5.0中通过
*/



/*请教一个问题,
一开始 我的include语句是#include <iostream>
编译器没说找不到文件iostream,而是未定义符号cout
*/

/*因为"语言由他们自己选择 " ,而Pasic,Basic等没有模板,所以这里也不用模板函数了*/
//---------------------------------------------------------------------------

//#pragma hdrstop
//#pragma argsused
#include <iostream.h>
//8:25begin 8:34End 8:45测试完 ;8:55
//ai是数组,acount是数组个数,result,是查找结果
bool FindTInArray(const int *iArray,const int iArrayCount,int const Seached,int &result)
{
int iBegin=0,iEnd=iArrayCount-1,iMiddle;
while(iEnd>iBegin){
//如果只有两个元素
if(iEnd==iBegin+1){
if(iArray[iEnd]==Seached){
result=iEnd;
return true;
}
if(iArray[iBegin]==Seached){
result=iBegin;
return true;
}
return false;
}

//正常折半查找
iMiddle=(iBegin+iEnd)/2;
if (iArray[iMiddle]==Seached){
result=iMiddle;
return true;
}
if(Seached>iArray[iMiddle]) iBegin=iMiddle;
else iEnd=iMiddle ;
}
return false;
}
int main(int argc, char* argv[])
{
int a[10]={0,1,2,3,4,5,6,7,8,9};
int searched=666;
int b;
if (FindTInArray(a,10,searched,b))
cout<<"变量searched:"<<searched<<",是数组a的第"<<b <<"个元素"<<endl;
else
cout<<"变量searched:"<<searched<<",不是数组a的元素"<<endl;
cin>>b; //让显示时停顿一下
return 0;
}
//---------------------------------------------------------------------------
langziji 2002-11-19
  • 打赏
  • 举报
回复
to AceVC(风) :size的奇偶性没有关系,你再仔细看看,我想二分查找也不是绝对的二分吧,只是分成两部分而已,你可以测一下看看。
ecivilian 2002-11-19
  • 打赏
  • 举报
回复
To wwwwbb78:
//设是升序排列
1.如果数组是0长度?
2.如果数组是1长度且==searched?
zhuxuwei 2002-11-19
  • 打赏
  • 举报
回复
如果说真正意义上的完全正确我想还没有一个程序员能够把那么多种的可能性都考虑进去吧!~~~~
我说得对吗?
我只是一个初学者啊!~~~~~!
xzhuang 2002-11-19
  • 打赏
  • 举报
回复
Knuth也说到过这个问题。第一个正确的二分查找法在197x年才出现。而二分查找法的概念196x年就有了。
langziji 2002-11-19
  • 打赏
  • 举报
回复
to AceVC(风) :size是奇数时,size/2不管是采取进一还是退一,只是把数组在这个位置分开,既然是奇数总有一个多一个少,我觉得没有什么不妥,我还是不解你的意思。
cwsheng 2002-11-18
  • 打赏
  • 举报
回复
能找到干麽自己写?还要上岗考试???
ltjpj 2002-11-18
  • 打赏
  • 举报
回复
"完全正确的"是一个太抽象的说法
frankxht 2002-11-18
  • 打赏
  • 举报
回复
我觉得要写出一个"完全正确的"二分法查找方法,应该用模板结构来写.就包含常见的类型int,float,char,char*...我想也要好好考虑一下了...至少1天吧.
langziji 2002-11-18
  • 打赏
  • 举报
回复
#include <stdio.h>
#include <stdlib.h>
/*data是数组首地址 size是数组大小
value要查找的数据值,可以通过定义全局而省去
base是data在主程序中的偏移位置*/
int DataSearch(int * data,int size,int value,int base)
{
if(size==1)
{
if(data[0]==value) return base+size-1;
else return -1;
}
if(data[size/2]==value) return base+size/2-1;
if(data[size/2]>value)
return DataSearch(data,size/2,value,base);
else
return DataSearch(data+size/2,size-size/2,value,base+size/2);

}

void main()
{
int * Data,Size,Value,Result,i;
printf("\nEnter the size:");
scanf("%d",&Size);
printf("\nEnter the value:");
scanf("%d",&Value);
Data=(int *)malloc(Size*sizeof(int));
for(i=0;i<Size;i++) Data[i]=i;/*可以通过别的方式赋值*/
Result=DataSearch(Data,Size,Value,0);
printf("\nResult is:%d\n",Result);
}

请大家帮助测试一下,这样写可以不?花时40分钟。
oldgameman 2002-11-18
  • 打赏
  • 举报
回复
其实我认为,Bently给我们出这道题的目的绝对不是考我们背书本的能力,更不是考我们对常用的算法的熟悉程度。
而是考我们将事物逻辑化的能力。是让我们去思考“为什么”而不是“是什么”
oldgameman 2002-11-18
  • 打赏
  • 举报
回复
int TwoSearch(int a[],int n,int data)
{
int p;
int low,high;
low=0;high=n-1;

while(low<=high)
{
p=a[(high+low)/2];
if(p==data)
return (high+low)/2; //返回Key所在的下标
else if(p>data)
high=(high+low)/2-1;
else
low=(high+low)/2+1;

}

return -1; //未找到
}

差三分钟到2小时,嘻嘻~~不过说实话真叫我凭空写我写不出来
一开始我凭空写的发现有几个逻辑错误,后来参考了正确的代码后才写出来上述的程序。
不过整体上思维是正确的,错的地方都是可以避免的:)
勉励前行 2002-11-18
  • 打赏
  • 举报
回复
用遞歸實現就難說是正確,難保不溢出。
貼主所說是用迭代實現的二分法,應該可行。不知為何說是不正確?
我覺得貼主所說方法是正確的,要通用可寫成模板。
template <class T>
int Numsear(vector<T>vec,T val)

//這裡跟貼主所貼完全一樣。因為我是抄的,所以用不了多少時間。

#include <vector.h>
#define NOTFOUNT -1
template <class T>
int Numsear(vector<T>vec,T val)
{
int low =0;
int high = vec.size() - 1;
while( low <= high )
{
int mid = ( low + high ) /2;
if( val == vec[mid] ) return mid;
if( val < vec[mid] ) high = mid -1;
else low = mid + 1;
}
return NOTFOUNT;
}
加载更多回复(32)

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧