比较K& R的两个binsesearch(数组索引与指针)

时间:2014-09-20 08:13:04

标签: c

我的问题在代码下面。

在结构一章中描述的K& R中有两个不同的bin搜索,一个使用数组索引来处理结构(p.134),另一个使用指向结构的指针(p.136)。

binsearch决定结构中的特定字符串keytab[n].word是否与数组中的字符串word匹配。

这是结构声明本身的初始化。该结构包含一堆c键盘及其出现的次数。

    struct key {
       char *word;
       int count;
   } keytab[] = {
       "auto", 0,
       "break", 0,
       "case", 0,
       "char", 0,
       "const", 0,
       "continue", 0,
       "default", 0,
       /* ... */
       "unsigned", 0,
       "void", 0,
       "volatile", 0,
       "while", 0
   };

这是第一个binsearch

/* binsearch:  find word in tab[0]...tab[n-1] */
   int binsearch(char *word, struct key tab[], int n)
   {
       int cond;
       int low, high, mid;

       low = 0;
       high = n - 1;
       while (low <= high) {
           mid = (low+high) / 2;
           if ((cond = strcmp(word, tab[mid].word)) < 0)
               high = mid - 1;
           else if (cond > 0)
               low = mid + 1;
           else
               return mid;
       }
       return -1;
   }

这是使用指向结构而不是数组索引的指针的binsearch:

/* binsearch: find word in tab[0]...tab[n-1] */
   struct key *binsearch(char *word, struct key *tab, int n)
   {
       int cond;
       struct key *low = &tab[0];
       struct key *high = &tab[n];
       struct key *mid;

       while (low < high) {
           mid = low + (high-low) / 2;
           if ((cond = strcmp(word, mid->word)) < 0)
               high = mid;
           else if (cond > 0)
               low = mid + 1;
           else
               return mid;
       }
       return NULL;
   }

有两件事我不明白。

首先,我们假设n是两种情况下结构数组的大小。

在第一个binsearch中,n-1被描述为搜索的最高限制。匹配字符串实际上可以在tab[high = n-1].word中出现,但不能出现在tab[n].word中。

在第二个bin搜索中,最高限制写为struct key *high = &tab[n],就像字符串可以在那里出现一样,即使“取消引用它也是非法的”(p.138,top)。它应该是NULL指针。

为什么不写为struct key *high = &tab[n-1]?像这样的数组似乎总是让我迷惑于c。

我不明白的第二件事是

high = mid;

在第二个binsearch中而不是

high = mid -1;

在第二个binsearch中。

为什么不是第二个high = mid-1

2 个答案:

答案 0 :(得分:1)

第一个问题的答案是,使用指针减法,你得到的是减去偏移的结果,IE low = &tab[0]high = &tab[n-1]high - low的结果是{{} 1}}而不是n-1。要获得中点,您需要nn),因此n/2应该等于high。第二个问题的答案是mid将永远比你感兴趣的元素高一个(因为我们知道它不是答案,并且它上面的所有元素都不是),所以它现在已经过了一个结束了您感兴趣的数组部分。因此,第一个问题的逻辑适用,我们将我们的高点放在我们数组的“结束”之后的一个位置。

答案 1 :(得分:1)

  

在第二个binsearch中,最高限制被写为struct key * high =&amp; tab [n],好像字符串可以出现在那里,即使“取消引用它是非法的”(p.138,top )。它应该是一个NULL指针。

不,它是空指针。它将指向超出数组末尾的第一个地址。您不能取消引用high,但可以在指针算术中使用它。

  

为什么不写为结构键* high =&amp; tab [n-1]?

因为如果让high将一个元素指向实际的上限,算法会更简单。

  

为什么不是第二个高=中1?

因为他们选择让high指向一个元素超过实际上限。这只是为了保持一致。

您可以像索引版本一样编写指针版本,其中高点指向实际元素,但您会发现此处需要进行+1-1调整。他们选择这样做的方式消除了大部分。