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