【问题标题】:Stuck in a while loop in cs50 pset3 binary search在 cs50 pset3 二进制搜索中陷入 while 循环
【发布时间】:2016-11-23 20:11:10
【问题描述】:

我正在尝试使用while 循环实现二进制搜索。当我正在寻找的int 在数组中时,它似乎有效;但是,当我正在搜索的 int 不存在时,程序似乎卡在循环中,而没有返回 false。我一直在使用gdb,但我似乎仍然无法找出错误。如您所见,我可能添加了一堆额外的 if 语句等,试图解决这个问题。

bool search(int value, int values[], int n) {
    sort(values, n);

    int begin = 0;
    int end = (n - 1);

    if (n < 1) {
        return false;
    }
    while (end > begin + 1) {
        int center = ((begin + end) / 2);
        if (values[0] == value) {
            return true;
        }
        if (begin == value) {
            return true;
        }
        if (end == value) {
            return true;
        }
        if (end == (begin + 1) || end == begin) {
            if (end == value || begin == value) {
                return true;
            } else {
                return false;
            }
        }
        if ((values[center]) == value) {
            return true;
        } else
        if ((values[center]) > value) {
            end = center;
        } else
        if ((values[center]) < value) {
            begin = center;
        } else {
            return false;
        }
    }
    // TODO: implement a searching algorithm
    return false;
}

【问题讨论】:

  • beginend 是索引,为什么要与 value 比较?
  • SO 上有很多可用的二分搜索算法(肯定有,其中相当一部分也与 CS50 相关)。您应该查看其中的一些,以发现您的代码过于复杂且不正确。例如,First and last occurrence for binary search in C 中有一些有用的代码,它处理了一些比您需要的更复杂的情况,但也包含您需要的代码。你也可以看看if statement not recognizing true conditions
  • @aknys:您可以通过单击分数下方的灰色复选标记来接受其中一个答案。

标签: c cs50


【解决方案1】:

你为什么要这样做?

if (values[0]==value)
    {
        return true;
    }
    if (begin == value)
    {
        return true;
    }
    if (end == value)
    {
        return true;
    }
    if (end == (begin+1) || end == begin)
    {
        if (end == value || begin == value)
        {
        return true;
        } 
        else
        {
        return false;
        }
    }

它们不是必需的。你可以像下面那样做

while(end>beg+1 && values[center]!=value)
     {
     if ((values[center])>value)
        end = center-1;
    else if (values[center]<value)
        begin = center+1;
    center=(end+begin)/2;
     }
     if(values[center]==value)
           return true;
     else return false;
    }

我不明白你为什么使用sort(values,n); 如果它是 C++ 代码,则将其用作 sort(values,values+n); 如果它是 C 代码,则使用任何 算法 根据您的数组 sizetime 对数组进行排序。 谢谢。

【讨论】:

    【解决方案2】:

    你不必要地把这个简单的事情复杂化了。 您可以删除代码中的所有额外内容并使用它

       `if ((values[center])==value)
        {
            return true;
        }
        else if ((values[center])>value)
        {
            end = center-1;
        }
        else if ((values[center])<value)
        {
            begin = center+1;
        }
    

    `

    【讨论】:

      【解决方案3】:

      您的代码太复杂了。以下是一些提示:

      • 您应该使用包含左侧索引而排除右侧索引的范围,这在 C 中是惯用的,并且会导致更简单的算法。

      • 如果startend 非常大,您应该计算center = start + (end - start) / 2; 而不是center = (start + end) / 2; 以避免潜在的整数溢出。

      • 数组大小应为size_t 类型,可能大于int

      • 将值与范围中间的元素的值进行比较:

        • 如果相等,则找到值,返回true。
        • 如果更小,则将范围缩小到左侧部分,排除中心。
        • 否则将范围缩小到右侧部分,排除中心。
      • 如果范围为空,则未找到该值,返回false。

      这是一个更简单的版本:

      bool search(int value, int values[], size_t n) {
          // Assuming values is sorted before calling this function
          //sort(values, n);
      
          size_t begin = 0;
          size_t end = n;
      
          while (begin < end) {
              size_t center = begin + (end - begin) / 2;
              if (value == values[center]) {
                  return true;
              }
              if (value < values[center]) {
                  end = center;
              } else {
                  begin = center + 1;
              }
          }
          return false;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-03-05
        • 2019-03-03
        • 2015-12-17
        • 2022-01-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-09
        相关资源
        最近更新 更多