C++ 通过对已排序向量进行二进制搜索来定位未排序向量中的元素
我一直在尝试只使用二进制搜索来获取元素在向量中的位置,没有循环,什么都没有,只使用库C++ 通过对已排序向量进行二进制搜索来定位未排序向量中的元素,c++,algorithm,vector,binary-search,C++,Algorithm,Vector,Binary Search,我一直在尝试只使用二进制搜索来获取元素在向量中的位置,没有循环,什么都没有,只使用库算法中的二进制搜索函数 由于二进制搜索函数只对已排序的容器类型起作用,我不知道如何获取原始向量中已搜索元素的位置,因为一旦对向量进行排序,搜索元素的位置可能与原始向量中的位置不同 我使用std::find编写代码,但我的主要目标是只使用二进制搜索函数 代码: #include <iostream> #include <vector> #include <algorithm>
算法中的二进制搜索函数
由于二进制搜索函数只对已排序的容器类型起作用,我不知道如何获取原始向量中已搜索元素的位置,因为一旦对向量进行排序,搜索元素的位置可能与原始向量中的位置不同
我使用std::find
编写代码,但我的主要目标是只使用二进制搜索函数
代码:
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
std::vector<int> v {1, 10, 100, -11, -112, -17, 44, -99, 99, 558};
std::vector<int> sorted = v;
std::sort(sorted.begin(), sorted.end());
std::cout << "Enter a number: ";
int number;
std::cin >> number;
if(std::binary_search(sorted.begin(), sorted.end(), number) == false)
{
std::cout << "There is no entered number.";
}
else
{
std::cout << "Number is located on position: ";
std::cout << std::find(v.begin(), v.end(), number) - v.begin();
}
return 0;
}
2°
因此,如果有人能帮助我使用二进制函数而不是std::find
,或者给我一些想法,我将非常感激
谢谢:)正如NathanOliver所指出的,不可能对未排序的数据进行二进制搜索
如果你的向量保证每个数字最多有一次,并且你不想改变顺序,那么你可以保留一个映射,该映射保留向量包含的每个int
的索引
map<int, size_t> idxMap;
如果您的内存不受限制,并且希望进行大量搜索,我建议您选择第一种方法。正如NathanOliver指出的,不可能对未排序的数据进行二进制搜索
如果你的向量保证每个数字最多有一次,并且你不想改变顺序,那么你可以保留一个映射,该映射保留向量包含的每个int
的索引
map<int, size_t> idxMap;
如果您没有内存限制,并且希望执行大量搜索,我建议您选择第一个选项。如果您希望执行二进制搜索,并将结果引用回原始未排序的数组,则需要执行索引排序和搜索,而不是对数组的副本进行排序和搜索,您可以对原始数组中的索引数组进行操作。比如:
std::vector<int> v {1, 10, 100, -11, -112, -17, 44, -99, 99, 558};
std::vector<int> sort_indexes(v.size());
for (size_t i = 0; i < v.size(); ++i)
sort_indexes[i] = i;
std::sort(sort_indexes.begin(), sort_indexes.end(),
[&v](int a, int b)->bool { return v[a] < v[b]; });
std::cout << "Enter a number: ";
int number;
std::cin >> number;
auto found = std::lower_bound(sort_indexes.begin(), sort_indexes.end(), number,
[&v](int a, int b)->bool { return v[a] < b; } );
if (found == sort_indexes.end() || v[*found] > number) {
std::cout << "There is no entered number." << std::endl;
} else {
std::cout << "Number is located on position: " << *found << std::endl;
}
std::向量v{1,10100,-11,-112,-17,44,-99,99558};
向量排序索引(v.size());
对于(大小i=0;ibool{returnv[a]number;
auto found=std::下限(排序索引.begin(),排序索引.end(),编号,
[&v](inta,intb)->bool{returnv[a]number){
std::cout如果要执行二进制搜索,并使结果引用回原始未排序数组,则需要执行索引排序和搜索,而不是对数组的副本进行排序和搜索,可以对原始数组中的索引数组进行操作。类似于:
std::vector<int> v {1, 10, 100, -11, -112, -17, 44, -99, 99, 558};
std::vector<int> sort_indexes(v.size());
for (size_t i = 0; i < v.size(); ++i)
sort_indexes[i] = i;
std::sort(sort_indexes.begin(), sort_indexes.end(),
[&v](int a, int b)->bool { return v[a] < v[b]; });
std::cout << "Enter a number: ";
int number;
std::cin >> number;
auto found = std::lower_bound(sort_indexes.begin(), sort_indexes.end(), number,
[&v](int a, int b)->bool { return v[a] < b; } );
if (found == sort_indexes.end() || v[*found] > number) {
std::cout << "There is no entered number." << std::endl;
} else {
std::cout << "Number is located on position: " << *found << std::endl;
}
std::向量v{1,10100,-11,-112,-17,44,-99,99558};
向量排序索引(v.size());
对于(大小i=0;ibool{returnv[a]number;
auto found=std::下限(排序索引.begin(),排序索引.end(),编号,
[&v](inta,intb)->bool{returnv[a]number){
std::难道你不能对未排序的数据集进行二进制搜索吗?算法的工作方式取决于排序的数据。你可以对包含原始索引的集合同时执行排序操作,并在搜索后查找原始位置。这比线性搜索慢,因此是p除非您需要多次搜索,否则retty毫无意义。您无法对未排序的数据集执行二进制搜索。算法的工作方式取决于正在排序的数据。您可以对包含原始索引的集合同时执行排序中的相同操作,并在搜索后查找原始位置。This比线性搜索慢,所以除非你需要多次搜索,否则它是毫无意义的。std::iota
删除显式循环以填充排序索引
。这回答了最初的问题,但我认为简单的find()
是一个更好的解决方案,至少对于一次性搜索来说是这样。它是O(n)vs.O(n log n)。如果您进行多次搜索,这可能是合理的。std::iota
删除显式循环以填充sort\u索引
。这回答了最初的问题,但我认为简单的find()
是一个更好的解决方案,至少对于一次性搜索是这样。这是O(n)与O(n log n)。如果您进行多次搜索,这可能是合理的。
std::vector<int> v {1, 10, 100, -11, -112, -17, 44, -99, 99, 558};
std::vector<int> sort_indexes(v.size());
for (size_t i = 0; i < v.size(); ++i)
sort_indexes[i] = i;
std::sort(sort_indexes.begin(), sort_indexes.end(),
[&v](int a, int b)->bool { return v[a] < v[b]; });
std::cout << "Enter a number: ";
int number;
std::cin >> number;
auto found = std::lower_bound(sort_indexes.begin(), sort_indexes.end(), number,
[&v](int a, int b)->bool { return v[a] < b; } );
if (found == sort_indexes.end() || v[*found] > number) {
std::cout << "There is no entered number." << std::endl;
} else {
std::cout << "Number is located on position: " << *found << std::endl;
}