二进制搜索字符串而不是数字

时间:2014-10-25 22:41:28

标签: c++ binary-search

我正在阅读关于数字数组的二进制搜索,我相信我知道它是如何工作的以及如何实现它。现在我需要知道如何对字符串数组进行二进制搜索?我知道二进制搜索需要对数组进行排序。假设我已经排序了一个字符串数组,如何在其上实现二进制搜索?我知道如果它是一个数字数组,我将转到数组的中间索引,并确定所需的搜索号是左侧还是右侧,并以递归方式执行。我如何为字符串做到这一点?

4 个答案:

答案 0 :(得分:1)

一种天真的方法是为每个字母分配一个唯一值(如果你正在做英文,那很容易;只有26个值),并比较每个字母的第一个字母的值。如果字母相同,则比较第二个字母,依此类推。

答案 1 :(得分:1)

如果您使用std::string数组,那么它就是相同的,因为您拥有所有比较运算符。

因此您只需要替换数组的类型,就可以按照数字进行搜索。

答案 2 :(得分:1)

只要"它的概念等于"并且"它小于"根据您正在处理的类型定义,您可以实现该算法。值是数字,字母还是自定义对象无关紧要。以下示例演示了此概念:

template<typename Iterator>                                                                         
Iterator search(Iterator initial, Iterator final, const typename Iterator::value_type& value) {     

  if(value < *initial) {
    // bail out immediately    
     return final;
   }

  while(initial != final) {                                                                         
    auto mid = std::next(initial, std::distance(initial, final) / 2);                               
    if(*mid == value) {                                                                             
      return mid;                                                                                   
    } else if(*mid < value) {                                                                       
      initial = std::next(mid);                                                                     
    } else {                                                                                        
      final = std::prev(mid);                                                                       
    }                                                                                               
  }                                                                                                 
  return final;                                                                                     
}    

只要定义了操作*mid == value*mid < value,我就可以搜索任何类型的容器(另一个要求是我必须能够随机访问我的迭代器)。

这绝不是一个完整的答案,还有更多的细节,但希望你能得到这个想法。

完整示例程序:

#include <vector>
#include <list>
#include <iostream>

template<typename Iterator>
Iterator search(Iterator initial, Iterator final, const typename Iterator::value_type& value) {

  if(value < *initial) {
    // bail out immediately    
     return final;
   }

  while(initial != final) {
    auto mid = std::next(initial, std::distance(initial, final) / 2);
    if(*mid == value) {
      return mid;
    } else if(*mid < value) {
      initial = std::next(mid);
    } else {
      final = std::prev(mid);
    }
  }
  return final;
}


int main() {
  {
    std::vector<int> v {1, 2, 3, 4, 5};
    auto it = search(v.begin(), v.end(), 3);
    if(it == v.end()) {
      std::cout << "Not Found!" << std::endl;
    } else {
      std::cout << "Found in position: " << std::distance(v.begin(), it)
                << " (value is : " << *it << ")" << std::endl;
    }
  }

  {
    std::vector<char> v {'a', 'b', 'c', 'd', 'e'};
    auto it = search(v.begin(), v.end(), 'd');
    if(it == v.end()) {
      std::cout << "Not Found!" << std::endl;
    } else {
      std::cout << "Found in position: " << std::distance(v.begin(), it)
                << " (value is : " << *it << ")" << std::endl;
    }
  }

  {
    std::list<float> v {-1, 0, 1, 2, 3, 4};
    auto it = search(v.begin(), v.end(), 0);
    if(it == v.end()) {
      std::cout << "Not Found!" << std::endl;
    } else {
      std::cout << "Found in position: " << std::distance(v.begin(), it)
                << " (value is : " << *it << ")" << std::endl;
    }
  }

  {
    std::vector<char> v {'a', 'b', 'c', 'd', 'e'};
    auto it = search(v.begin(), v.end(), 'f');
    if(it == v.end()) {
      std::cout << "Not Found!" << std::endl;
    } else {
      std::cout << "Found in position: " << std::distance(v.begin(), it)
                << " (value is : " << *it << ")" << std::endl;
    }
  }

}                                                                                        

示例运行:

Found in position: 2 (value is : 3)
Found in position: 3 (value is : d)
Found in position: 1 (value is : 0)
Not Found!

答案 3 :(得分:0)

完全相同的方式。如果您使用std::string,则它已经具有operator==operator <,这些都是二进制搜索所需的全部内容。如果你只有字符指针,你可以使用strcmp,其中负值小于0且0相等。