【问题标题】:Buggy simple function for binary search (C++)用于二分搜索的错误简单函数 (C++)
【发布时间】:2017-03-24 19:49:14
【问题描述】:

我为二进制搜索编写了一个简单的函数,但它没有按预期工作。我有一个包含 4000000 个 32 位整数的向量。通常,当我搜索一个数字时,如果存在,则找到并返回索引,如果不存在,则返回-1(索引始终与值对应,但这不是重点)。

在玩弄程序时发现它找不到 93(即使它在那里),显然,它找不到更多的值。

我使用 CLion,它将 GDB 实现为调试器,将 G++ 实现为编译器。

template<typename T>
int BinarySearch(vector<T>& vec, T& request)
{

    int low = 0;
    int high = vec.size() - 1;

    while (low < high)
    {
        int mid = (low / 2 ) + (high / 2); // Styled it this way to avoid overflows. 
// This looks like where the bug happens, basically low and high both 
// become 93 while mid becomes 92,
// it then exits the loop and returns -1 because low is not lower than
// high anymore.

        if (vec[mid] == request)
        {
            return mid;
        }
        else if (vec[mid] < request)
        {
            low = mid + 1;
        }
        else if (vec[mid] > request)
        {
            high = mid - 1;
        }

    }
    return - 1;

}

我很困惑,这是怎么回事?

【问题讨论】:

  • 高界不是专属吗?例如。 T 高 = vec.size();
  • 节省一些开发时间并使用:std::binary_searchstd::lower_boundstd::upper_bound。他们已经过彻底的测试。不要重写轮子。
  • @ThomasMatthews 尽管我从未使用过它们,但我知道它们的存在。我不是要重新发明轮子,只是尝试一下。
  • 我确信由于索引值的舍入,一定存在边缘条件。您是否学习过调试的高级艺术,但是,您使用调试器的地方,或者在转储相关数据的地方到处粘贴语句以进行分析?如果没有,您应该考虑花一些时间来获得一些基本的调试技能。这样做肯定会更快,并且能够快速定位自己的错误,而不是等待 stackoverflow.com 上有时间在其他人的代码中查找错误的人。
  • 如果您手动计算,您会发现 92/2 + 93/2 确实是 92。它应该是 92,因为整数数学就是这样工作的。因此,你必须弄清楚你的逻辑有什么问题。

标签: c++ linux g++ binary-search-tree


【解决方案1】:

条件应该是while (low &lt;= high)

如果将其保留为while (low &lt; high),那么当low==high(意味着我们到达最后一个元素)时,while 循环将中断并返回-1。因此,您的程序不会检查该元素。

此外,您应该使用mid=low+(high-low)/2; 来防止溢出并访问所有值。
您的代码中的问题是假设当low=high=1 时,它会给出mid=0(由于数据转换),这是错误的。

【讨论】:

  • 不工作,搜索93会卡在无限循环中
  • 工作!!谢谢!
  • 等等,由于某种原因 high 超过了它最初分配的值,问题必须是 mid=low+(high-low)/2,但是为什么呢?我尝试搜索 5000000 并找到它,即使向量仅包含 4000000 个元素。这是为什么呢?
  • 哦等等,问题是在将循环从while (low
  • “我尝试搜索 5000000,即使它包含 4000000 个元素”是什么意思?在二进制搜索中,你搜索一个不是索引的值
猜你喜欢
  • 1970-01-01
  • 2021-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多