对于C ++语言,处理运行时(在多核处理器中)的最快方法是什么,从算法设计的角度来看,搜索数组内的数字(例如100到1000之间)(或拼接或更快的速度)用于此目的的数据结构)并返回仅限于10项返回的数字范围?例如golang中的伪代码:
var listofnums := []uint64
var numcounter := 1
// splice of [1,2,3,4,5,31,32 .. 932536543] this list has 1 billion numeric items.
// the listofnums are already sorted each time an item is added but we do not know the lower_bound or upper_bound of the item list.
// I know I can use binary search to find listofnums[i] where it is smallest at [i] too... I'm asking for suggestions.
for i:=uint(0); i < len(listofnums); i++ {
if listofnums[i] > 100 && listofnums[i] < 1000 {
if listofnums[i]> 1000 || numcounter == 10 {
return
}
fmt.Println("%d",listofnums[i])
numcounter++
}
}
这是最快的方法吗?我在C ++中看到了位图结构,但不确定是否可以在这里应用。
我遇到过这个问题,这对于资深程序员来说是完全没问题,但我不知道为什么会被投票。 What is the fastest search method for array?
有人请不要删除这个问题,但让我改一下吗?提前致谢。我希望找到从大量数字项中返回一系列数字的最佳方法。
答案 0 :(得分:2)
如果我正确理解你的问题,你需要在你的数组中找到两个位置,第一个数字大于或等于100
,第二个位置所有数字都小于或等于{ {1}}。
函数std::lower_bound和std::upper_bound执行二元搜索,旨在找到这样的范围。
对于数组,在1000
中我们通常使用std::vector并使用一对迭代器表示范围的开头和结尾。
所以这样的事情可能就是你所需要的:
C++
你可以像这样迭代这个范围:
std::pair<std::vector<int>::iterator, std::vector<int>::iterator>
find_range(std::vector<int>& v, int min, int max)
{
auto begin = std::lower_bound(std::begin(v), std::end(v), min);
// start searching after the previously found value
auto end = std::upper_bound(begin, std::end(v), max);
return {begin, end};
}
您可以从范围(慢)创建一个新的向量,如下所示:
auto range = find_range(v, 100, 1000);
for(auto i = range.first; i != range.second; ++i)
std::cout << *i << '\n';
答案 1 :(得分:1)
我的第一次尝试。
特点:
logN时间复杂度
创建一个数组切片,不复制数据
第二次二进制搜索在第一次
可能的改进:
#include <vector>
#include <cstdint>
#include <algorithm>
#include <iterator>
#include <iostream>
template <class Iter> struct range
{
range(Iter first, std::size_t size) : begin_(first), end_(first + size) {}
auto begin() const { return begin_; }
auto end() const { return end_; }
Iter begin_, end_;
};
template<class Iter> range(Iter, std::size_t) -> range<Iter>;
auto find_first_n_between(std::vector<std::int64_t>& vec,
std::size_t n,
std::int64_t from, std::int64_t to)
{
auto lower = std::lower_bound(begin(vec), end(vec), from);
auto upper = std::upper_bound(lower, end(vec), to);
auto size = std::min(n, std::size_t(std::distance(lower, upper)));
return range(lower, size);
}
int main()
{
std::vector<std::int64_t> vec { 1,2,3,4,5,6,7,8,15,17,18,19,20 };
auto slice = find_first_n_between(vec, 5, 6, 15);
std::copy(std::begin(slice), std::end(slice), std::ostream_iterator<std::int64_t>(std::cout, ", "));
}