【问题标题】:Binary Search Function in C++ returns infinite loopC ++中的二进制搜索函数返回无限循环
【发布时间】:2016-05-03 13:52:44
【问题描述】:

好吧,这更像是一个查询,所以我可以理解它在做什么,但是,我有以下代码。照原样,while 循环将返回一个无限循环,我将 while 更改为基本的for(int i=0;i<n;i++) 循环,它可以正常工作并输出。

发生了什么?我实际上不知道为什么我的 while 循环会卡住,但 for 循环不会。

bool binary_search(const string A[], int n, string name, int &count){
   count = 0;                  // Count initialization
   int fst = 0;
   int lst = n+1;              // First, Last and Middle array elements
   int mid = 0;

   while(fst<=lst)
   {
      count++;

      mid = (fst+lst)/2;      // Calculate mid point of array
      if (A[mid]==name)       // If value is found at mid
      {
         return true;
      }
      else if (A[mid]>name)
      {                       // if value is in lower
         lst = mid++;
         //cout << "elseIfME!" << endl;
      }
      else if (A[mid]<name)
      {                       // if value is in higher
         fst = mid--;
         //cout << "elseME!" << endl;
      }
   }
   return false;

}

【问题讨论】:

  • 您在分配给fst/lst 时发布增量/减量是无用的。

标签: c++ for-loop while-loop binary-search


【解决方案1】:

你的条件应该是这样的 ::

// Assuming that the array you are searching is sorted in descending order
// and hence the else-if conditions
else if (A[mid]>name)
{                       
   lst = mid + 1;
}
else if (A[mid]<name)
{      
   fst = mid - 1;
}

您使用的后期增量是无用的!因为,当您发布增量(mid++mid--)时,它会返回原始值(mid),然后该值会递增/递减,所以实际上,您在您的每次找不到元素时都要编码。

所以,当fst = lst 在二分搜索期间您将数组中的搜索域缩短为仅 1 个元素时,您计算出的mid 等于fstlst,如果未找到该元素,您可以分配fst = midlst = mid,因为这是您的循环应该停止的地方,并且要停止条件fst &lt;= lst 将被违反,这不是,因此是无限循环。

即使在搜索过程中,当您通过比较中心元素来缩小搜索范围时,您也必须排除刚刚比较的中心元素,因为后期增量,您没有这样做!

如果您希望它起作用,您也可以使用预增量和预减量! (++mid--mid

【讨论】:

  • 啊,所以我猜 mid++
  • @pacificfrost 它没有什么比它最好的循环或任何东西,你只需要确定什么时候更新值,就像,即使使用后增量你可以写mid++; lst = mid,因为当你在增量后的下一条语句中,mid 已更新,它将起作用,这取决于您要完成的操作!
  • 啊。我现在知道了。谢谢!一旦我在课堂上完成了这个概念,我就会玩这个概念,希望一旦我玩过它,我可以修复 while 循环来为我工作。
【解决方案2】:

我认为你的逻辑是倒退的。 if (A[mid]&gt;name) 为真,则 name 位于列表的下半部分,但您正在增加超过此点的中间部分,进入列表中无法包含的部分。在这种情况下,您应该设置 lst = mid-1,不是mid--,因为它将 lst 设置为 mid,然后将其递减。同样的测试if (A[mid]&lt;name),你应该设置 fst = mid + 1,比如:

  else if (A[mid]>name)
  {                       // if value is in lower
     lst = mid - 1;
     //cout << "elseIfME!" << endl;
  }
  else if (A[mid]<name)
  {                       // if value is in higher
     fst = mid + 1;
     //cout << "elseME!" << endl;
  }

基本上,您的原始逻辑在确定值应位于列表的哪个部分时,会增加该部分的大小,而不是缩短它,因此您只需继续搜索更大的子列表,而不是更小的子列表。

【讨论】:

  • @Jarod42 这个问题没有提到数组是按升序还是降序排序的!
  • 谢谢!我非常感谢您的解释!
  • 而且,我验证了它,因为对我来说它更清楚一点,我更理解解释,它也回答了我想问的问题。
猜你喜欢
  • 1970-01-01
  • 2021-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-15
相关资源
最近更新 更多