【问题标题】:BinarySearch returning index of where it belongsBinarySearch 返回它所属位置的索引
【发布时间】:2013-10-26 07:07:11
【问题描述】:

所以我希望编写一个代码来返回键所在的索引,或者如果它不存在,它应该在哪里。我错过了什么? min 为 0,max 为 size - 1,buf 已排序

int binarySearch(string buf[], string key, int min, int max){

int mid;
while (max >= min){
    mid = (min + max) / 2;

    if (buf[mid] < key)
        min = mid + 1;
    else if (buf[mid] > key)
        max = mid - 1;

    else
        return mid;

}
return min;
}

【问题讨论】:

  • 是的,它不起作用,当字符串不存在时它不会返回正确的索引。
  • 如果字符串不存在,则没有“正确”索引。您究竟打算如何传播返回的索引“应该”在哪里与它“在”哪里的信息?通过该索引取消引用并进行比较?那买你...?这个问题的臭味几乎像an XY problem 一样强烈。也就是说,您可以使用std::lower_bound 轻松完成此操作,只需大约 3 行代码(大约)。
  • 确实,进行二分搜索同样便宜,如果不存在,则进行线性插入,因为无论如何您都需要移动所有元素以使其进入正确的位置。
  • long idx = (std::lower_bound(buf+min, buf+max+1, key) - buf); 应该这样做。
  • 好吧,这种二分搜索被另外两种方法使用:查找和插入。 insert 调用 binarysearch 并且索引始终是重复的索引或应插入字符串以保持列表排序的地址。对于查找,您只需检查 buf[index] == 我们正在寻找的字符串。

标签: c++ sorting binary-search-tree


【解决方案1】:

我实际上遇到了同样的问题,所以我编写了这个通用代码(也许您可能想要使用与 std 不同的命名空间;))下面的代码将迭代器返回到序列中小于或的最大元素等于 val。对于 N = std::difference(first, last),它使用 O(N log N) 时间,假设在 [first ... last) 上随机访问 O(1)。

#include <iostream>
#include <vector>
#include <algorithm>

namespace std {

template<class RandomIt, class T>
RandomIt binary_locate(RandomIt first, RandomIt last, const T& val) {
  if(val == *first) return first;
  auto d = std::distance(first, last);  
  if(d==1) return first;
  auto center = (first + (d/2));
  if(val < *center) return binary_locate(first, center, val);
  return binary_locate(center, last, val);
}  

}

int main() {
    std::vector<double> values = {0, 0.5, 1, 5, 7.5, 10, 12.5};
    std::vector<double> tests = {0, 0.4, 0.5, 3, 7.5, 11.5, 12.5, 13};
    for(double d : tests) {
        auto it = std::binary_locate(values.begin(), values.end(), d);
        std::cout << "found " << d << " right after index " << std::distance(values.begin(), it) << " which has value " << *it << std::endl;
    }
    return 0;
}

来源:http://ideone.com/X9RsFx

代码非常通用,它接受 std::vectors、std::arrays 和数组,或任何允许随机访问的序列。假设(读取前提条件)是 val >= *first 并且值 [first, last) 已排序,就像 std::binary_search 所需的那样。

请随意提及我使用过的错误或不当行为。

【讨论】:

    【解决方案2】:
    int binary_srch_ret_index(ll inp[MAXSIZE], ll e, int low, int high) {
    
        if (low > high) {
            return -1;
        }
    
        int mid = (low + high) / 2;
    
        if (e == inp[mid]) {
            return mid;
        }
    
        if (e < inp[mid]) {
            return binary_srch(inp, e, low, mid - 1);
        } else {
            return binary_srch(inp, e, mid + 1, high);
        }
    }
    

    【讨论】:

      【解决方案3】:

      您搜索了一个字符,并假设 buf 中的字符已排序。

      如果要搜索字符串,请使用字符串匹配模式算法。 (http://en.wikipedia.org/wiki/String_searching_algorithm)

      如果您想在有序数组中搜索字符或数字,请查看以下内容: http://www.programmingsimplified.com/c/source-code/c-program-binary-search

      【讨论】:

        【解决方案4】:

        在二进制搜索中,您可以进行值类型搜索而不是引用类型。如果你想在字符串数组中搜索字符串,你必须编写一个复杂的程序或使用 has table

        【讨论】:

        • 我很确定你可以做到这一点。这只是一个逻辑错误,我无法正确计算算法。
        【解决方案5】:

        这似乎有效:

        #include <iostream>
        #include <cassert>
        
        int binarySearch(int buf[], int key, int min, int max);
        
            int main()
        {
            int data[] = {1,2,4,6,7,9};
        
            for(int i=0; i<6; i++)
            {
                int result = binarySearch(data, data[i], 0, 5);
                assert(result == i);
            }
        
            assert(binarySearch(data, 3, 0, 5) == 1);
            assert(binarySearch(data, 5, 0, 5) == 2);
            assert(binarySearch(data, 8, 0, 5) == 4);
            assert(binarySearch(data, 10, 0, 5) == 5);
        
            return 0;
        }
        
        
        
        int binarySearch(int buf[], int key, int min, int max)
        {
            int mid;
            while (max >= min){
                mid = (min + max) / 2;
        
                if (buf[mid] < key)
                    min = mid + 1;
                else if (buf[mid] > key)
                    max = mid - 1;
        
                else
                    return mid;
        
            }
            return std::min(min, max);
        }
        

        【讨论】:

        • 该函数需要返回应该放置比较键的索引,而不是只查找它是否在那里..所以不能返回-1
        • 将修复,给我几秒钟
        • 那里,这些测试至少通过了。添加了对 -3 的测试,返回 -1,所以这似乎也有效。它返回的索引号是它应该在之后的数字,或者是它的数字。
        • 由于某种原因它仍然无法正常工作。!感谢您的帮助
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-26
        • 1970-01-01
        • 2013-10-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多