青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆-80  評論-24  文章-0  trackbacks-0
今天看編程之美,3.11里面有個改錯題,是針對一個二分查找算法的糾錯,先說下題目:找出一個有序(字典序)字符串數組arr中值等于字符串v的元素的序號,如果有多個元素滿足條件,則返回其中序號最大的。
要說算法這個問題確實不難,但是寫程序的話需要注意一些地方,書中已經寫的比較完美了,就不貼了,這里貼一個通用版本,也是模仿斯坦福公開課《編程范式》中講解的來寫的,這個bisearch()和c庫中的bsearch()很像。

 1 int bisearch(const void *arr, 
 2     const void *elem, 
 3     int elem_size, 
 4     int elem_num, 
 5     int (*fcmp)(const void *, const void *)) {
 6   int low = 0;
 7   int high = elem_num - 1;
 8   int mid;
 9 
10   while (low < high - 1) {
11     mid = ((high - low) >> 1) + low;
12     int status = 
13       fcmp((const void *)((char *)arr + mid * elem_size), 
14           (const void *)elem);
15     if (status <= 0) {
16       low = mid;
17     } else {
18       high = mid;
19     }
20   }
21 
22   if (fcmp((const void *)((char *)arr + high * elem_size), 
23         (const void *)elem) == 0) {
24     return high;
25   } else if (fcmp((const void *)((char *)arr + low * elem_size), 
26         (const void *)elem) == 0) {
27     return low;
28   } else {
29     return -1;
30   }
31 }
32 

可以看到如果題目變一下,那么上面的函數也需要改變,比如,如果有多個元素滿足這個條件,則返回最小的序號,那么程序修改如下:

int bisearch(const void *arr, 
    const void *elem, 
    int elem_size, 
    int elem_num, 
    int (*fcmp)(const void *, const void *)) {
  int low = 0;
  int high = elem_num - 1;
  int mid;

  while (low < high - 1) {
    mid = ((high - low) >> 1) + low;
    int status = 
      fcmp((const void *)((char *)arr + mid * elem_size), 
          (const void *)elem);
    if (status >= 0) {
      high = mid;
    } else {
      low = mid;
    }
  }

  if (fcmp((const void *)((char *)arr + low * elem_size), 
        (const void *)elem) == 0) {
    return low;
  } else if (fcmp((const void *)((char *)arr + high * elem_size), 
        (const void *)elem) == 0) {
    return high;
  } else {
    return -1;
  }
}

其實也就是修改一下比較的順序。
如果要求大于v的最小的數組元素的序號i呢?我們依然先求等于v的最大的序號j,不過在確定low和high之后,需要如下考慮:
若arr[low] > v,那么我們可以肯定low即為i
若arr[high] < v,那么我們也可以肯定沒有比v大的元素,返回-1
若arr[high] == v,那么如果high = elem_num - 1,則說明數組中所有元素都小于等于v,則返回-1,否則返回high + 1
否則返回high
程序如下:

 1 int bisearch(const void *arr, 
 2     const void *elem, 
 3     int elem_size, 
 4     int elem_num, 
 5     int (*fcmp)(const void *, const void *)) {
 6   int low = 0;
 7   int high = elem_num - 1;
 8   int mid;
 9 
10   while (low < high - 1) {
11     mid = ((high - low) >> 1) + low;
12     int status = 
13       fcmp((const void *)((char *)arr + mid * elem_size), 
14           (const void *)elem);
15     if (status <= 0) {
16       low = mid;
17     } else {
18       high = mid;
19     }   
20   }
21 
22   int stlow = 
23     fcmp((const void *)((char *)arr + low * elem_size), 
24         (const void *)elem);
25   int sthigh = 
26     fcmp((const void *)((char *)arr + high * elem_size), 
27         (const void *)elem);
28   if (stlow > 0) {
29     return low;
30   } else if (sthigh < 0) {
31     return -1; 
32   } else if (sthigh == 0) {                                                                                                  
33     if (high == elem_num - 1) {
34       return -1; 
35     } else {
36       return high + 1;
37     }   
38   }
39   return high;
40 }

如果要求小于v的最大的數組元素的序號i呢?我們依然先求等于v的最小的序號j,不過在確定low和high之后,需要如下考慮:
若arr[low] > v,那么我們可以肯定沒有比v大的元素,返回-1 
若arr[high] < v,那么返回high
若arr[low] == v,那么如果low = 0,則說明數組中所有元素都大于等于v,則返回-1,否則返回low - 1
否則返回low
程序如下: 

 1 int bisearch(const void *arr, 
 2     const void *elem, 
 3     int elem_size, 
 4     int elem_num, 
 5     int (*fcmp)(const void *, const void *)) {
 6   int low = 0;
 7   int high = elem_num - 1;
 8   int mid;
 9 
10   while (low < high - 1) {
11     mid = ((high - low) >> 1) + low;
12     int status = 
13       fcmp((const void *)((char *)arr + mid * elem_size), 
14           (const void *)elem);
15     if (status >= 0) {
16       high = mid;
17     } else {
18       low = mid;
19     }   
20   }
21 
22   int stlow = 
23     fcmp((const void *)((char *)arr + low * elem_size), 
24         (const void *)elem);
25   int sthigh = 
26     fcmp((const void *)((char *)arr + high * elem_size), 
27         (const void *)elem);
28   if (stlow > 0) {
29     return -1; 
30   } else if (sthigh < 0) {
31     return high;
32   } else if (stlow == 0) {
33     if (low == 0) {
34       return -1; 
35     } else {
36       return low - 1;
37     }   
38   }
39   return low;
40 }
posted on 2012-09-02 18:37 myjfm 閱讀(538) 評論(1)  編輯 收藏 引用 所屬分類: 算法基礎

評論:
# re: 二分查找剖析 2013-04-07 13:05 | jq
最后一例:要求小于v的最大的數組元素的序號i
最后的判斷似乎不夠簡潔,想探討一下,盼賜教,多謝

28 if (stlow > 0) {
29 return -1;
30 } else if (sthigh < 0) {
31 return high;
32 } else if (stlow == 0) {
33 if (low == 0) {
34 return -1;
35 } else {
36 return low - 1;
37 }
38 }
39 return low;

感覺可以優化為下列:
if(sthigh<0) {
return high;
} else if(stlow<0) {
return low;
}
else {
return -1;
}
因為36行永遠不會執行到:
若stlow==0, 則low == 0
反正法: 若 low>0且stlow==0, 因為剛開始low=0, 所以必定在while循環中被改變:
而low被修改的前提條件: arr[mid]< elem , 所以被改后 low=mid, arr[low]<element==>stlow!=0
  回復  更多評論
  
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产在线精品一区二区夜色| 欧美三级第一页| 狠狠色狠狠色综合日日tαg| 久久www成人_看片免费不卡| 欧美怡红院视频| 影院欧美亚洲| 亚洲人精品午夜| 欧美视频日韩| 久久精品欧美| 麻豆成人精品| 亚洲素人一区二区| 性欧美8khd高清极品| 一区二区三区自拍| 亚洲区免费影片| 国产精品久久久久av| 久久久国产精品亚洲一区| 久久综合九九| 午夜国产精品影院在线观看| 久久高清福利视频| 一本色道久久综合亚洲精品小说| 这里只有精品在线播放| 韩国精品久久久999| 亚洲国产婷婷| 国产精品丝袜白浆摸在线| 美女免费视频一区| 欧美日韩在线一区二区| 久久久xxx| 欧美日韩国产123| 久久久久天天天天| 欧美日韩一区二区三区高清| 久久久久久久久久看片| 欧美日韩免费看| 久久亚洲国产成人| 欧美午夜久久| 亚洲高清在线| 国产日韩专区| 中国成人在线视频| 亚洲美女在线看| 久久久久久久久久久久久久一区| 一区二区不卡在线视频 午夜欧美不卡在 | 亚洲第一精品影视| 国产欧美日本一区二区三区| 亚洲精品黄色| 亚洲国产婷婷| 久久精品视频va| 欧美日韩国产页| 欧美视频三区在线播放| 久久婷婷av| 国产精品成人aaaaa网站| 欧美国产精品专区| 国产一区二区三区在线观看网站 | 欧美刺激午夜性久久久久久久| 欧美视频一区在线| 亚洲第一天堂无码专区| 激情一区二区三区| 性伦欧美刺激片在线观看| 亚洲宅男天堂在线观看无病毒| 欧美fxxxxxx另类| 久久中文在线| 激情五月婷婷综合| 欧美永久精品| 久久国产精品99久久久久久老狼| 欧美日韩综合精品| 亚洲精品国产精品国自产在线 | 亚洲男人的天堂在线| 欧美激情自拍| 亚洲精品在线二区| 99精品欧美一区二区三区| 欧美韩日视频| 亚洲人在线视频| 日韩小视频在线观看专区| 欧美成人中文| 亚洲精品久久7777| 一级日韩一区在线观看| 欧美日韩综合精品| 亚洲午夜伦理| 久久久91精品国产一区二区精品| 国产日韩欧美一区在线 | 亚洲日本一区二区| 在线亚洲免费| 国产精品网站在线观看| 欧美一区二区性| 久久字幕精品一区| 亚洲片在线观看| 欧美日韩在线播放一区二区| 亚洲性色视频| 久久天天躁狠狠躁夜夜av| 亚洲电影免费在线| 欧美日韩国产一区精品一区| 一区二区三区日韩欧美精品| 欧美在线91| 亚洲激情视频在线播放| 欧美日韩一卡二卡| 午夜精品一区二区三区在线| 免费成人高清视频| 夜夜精品视频| 国产主播精品| 欧美啪啪一区| 久久本道综合色狠狠五月| 欧美二区在线播放| 亚洲免费影视| 亚洲国产精品99久久久久久久久| 欧美日韩精品不卡| 久久黄色网页| 9久re热视频在线精品| 久久久久综合| 亚洲主播在线观看| 亚洲黄色一区| 国产午夜精品一区二区三区视频| 欧美成人激情在线| 新67194成人永久网站| 亚洲人成网站在线观看播放| 欧美一区二区三区久久精品| 亚洲日韩视频| 国产亚洲制服色| 欧美视频不卡中文| 欧美1区2区3区| 亚洲在线播放| 一区二区日韩免费看| 老巨人导航500精品| 欧美一级在线视频| 一本久久综合亚洲鲁鲁| 亚洲国产成人不卡| 国产亚洲激情| 国产乱肥老妇国产一区二| 欧美精品在线观看一区二区| 久久一本综合频道| 欧美在线视频观看免费网站| 在线一区二区日韩| 亚洲免费观看视频| 亚洲成色777777女色窝| 久久婷婷国产综合国色天香| 西瓜成人精品人成网站| 亚洲天堂成人在线视频| 亚洲伦伦在线| 亚洲乱码精品一二三四区日韩在线 | 美国成人毛片| 久久噜噜亚洲综合| 久久精品免费看| 欧美一区日韩一区| 亚洲欧美视频一区二区三区| 一区二区三区视频在线| 亚洲久色影视| 99精品热6080yy久久| 99riav1国产精品视频| 亚洲三级国产| 亚洲精品系列| av成人激情| 亚洲视频电影在线| 中文国产成人精品| 亚洲午夜在线观看| 亚洲欧美国产不卡| 午夜在线电影亚洲一区| 久久精品99久久香蕉国产色戒| 久久xxxx精品视频| 久热这里只精品99re8久| 久久婷婷人人澡人人喊人人爽 | 亚洲欧洲日本一区二区三区| 亚洲国产视频a| 99视频在线观看一区三区| 亚洲视屏一区| 欧美一区二区播放| 久久久激情视频| 欧美成人免费全部观看天天性色| 欧美大尺度在线观看| 欧美日韩在线播放三区四区| 国产精品日产欧美久久久久| 国产一区二区三区不卡在线观看| 在线播放豆国产99亚洲| 亚洲精品激情| 亚洲尤物影院| 久久在精品线影院精品国产| 亚洲电影在线| 亚洲综合成人在线| 久久夜色精品国产欧美乱| 欧美日韩亚洲成人| 国产一区欧美日韩| 亚洲精品一区二区三区在线观看| 亚洲欧美久久久久一区二区三区| 久久久久久久尹人综合网亚洲| 免费久久99精品国产自| 夜夜嗨av一区二区三区免费区| 欧美一进一出视频| 欧美日韩国产综合久久| 国内精品视频一区| 亚洲制服丝袜在线| 欧美福利视频在线| 香蕉国产精品偷在线观看不卡| 欧美高清免费| 国产专区精品视频| 一区二区三区久久精品| 久久综合九色综合欧美狠狠| 宅男噜噜噜66一区二区66| 久久久久国产精品厨房| 国产精品成人一区二区三区吃奶| 亚洲高清资源| 久久se精品一区二区| 一本大道av伊人久久综合| 老色批av在线精品| 国产亚洲福利|