问题不难,如果是你,这几句代码怎么优化呢?(50分)

  • 主题发起人 主题发起人 张辉明
  • 开始时间 开始时间

张辉明

Unregistered / Unconfirmed
GUEST, unregistred user!
代码一:网上的的代码(http://www.moon-soft.com/doc/30984.htm)
5.二分查找法.对已排序序列进行查找
function BinarySearch(SearchNum:array of integer;x,n:integer):integer;//序列,值,序列长度
var left,right,mid:integer;
begin
result:=-1;
left:=0;right:=n-1;
while(left<=right)do
begin
mid:=(left+right) div 2;
if x=SearchNum[mid] then
begin
result:=mid;
exit;
end;
if x>SearchNum[mid] then left:=mid+1
else right:=mid-1
end;
end;


方法二:(某开源软件的代码)
function TList.BinarySearch(Compare: TListFindCompareMethod; const Value;
var Index: Integer): Boolean;
var
L, H, I, C: Integer;
begin
Result := False;
L := 0;
H := Count - 1;
while L <= H do
begin
I := (L + H) shr 1;
C := Compare(Items, Value);
if C < 0 then L := I + 1 else
begin
H := I - 1;
if C = 0 then
Result := True;
end;
end;
Index := L;
end;

如果是你怎么写呢?要求易懂,效率高。还是用二分法。
 
以上两个写法完全一样。如果你要说整数比较和Compare(Items, Value)比较的差别 那说明你还没懂二分查找的基本意思。
 
两个二分法,虽然结果都是正确的,但还是有区别的,如果完全一样,我也不会拿出来,让大家点评,请二楼仔细看清帖子的题目,再来回答问题。
 
区别? 撇开Compare(); 也就 shr 可能比 div 高效一点, 一个通过Result返回结果,一个通过var index返回结果 还有就是是否先比较"相等"了
感觉差不多吧, 方法二更高效一点
 
呵呵,可惜啊,难怪DFW走了那么多的人,可能是正好周末吧,我再等等
 
莫非你是想说,用回调函数比较通用些?
 
应该说,我会用第二种写法,
1、主体算法上没什么大区别
2、做成类,把数据和方法封装在一起
3、采用回调函数,可以更通用的处理各种数据类型
4、查找结果通过var变量传出,函数返回值包含函数执行结果,这种写法好
 
呵呵 还是没讲到点子上来,说明很多人看程序还是不够细心。
我贴来这两个二分法让大家分析,就是因为它简单,花不了多少时间。但是确实两个二分法
之间又有区别的。如果因为那个回调函数,根本不值得拿出来。

  还是自己给出答案了。

  代码一中找到正确值的处理方式:
   result:=mid;
exit;
  这样做,一旦找到了,就设置返回值,并立即退出循环。

  但是代码二中找到正确时,却有所不同,请看:
if C = 0 then
Result := True;
  然后继续做循环,只到L<=H不成立!

  最后循环退出后,再设定返回值为  Index := L;

这时可以看出,方法二明显比方法多循环几次,如果数组大,或者在比较巧在开始就找到的话那么要多循环好多次。到这里问题就来了,这样做有必要吗,应该可以优化啊?
是的,在这里二分法查找中如果按照代码一的方式,找到结果立即跳出循环,可以提高效率。但是如果找不到呢?一个业务逻辑中往往有查找,删除,插入等操作。一般情况下,如果找不到元素都要做插入操作,哈哈这里有第二代码就方便了。看看的返回值吧,呵呵,已经在那里了。
 
为什么是 EXIT,而不是 BREAK;跳出循环呢.
 
嗯,是没注意到,你一说就很明显了,呵呵,太粗心了。
 
后退
顶部