从一系列整数中搜索
Search from a range of integers
我需要从整数列表中查找一个整数。我对它们进行排序,并使用lower_bound来找到给定整数的范围。这需要O(lgn)。有什么办法比这更好吗?
以下是需要改进的提示。
- 给定列表总是正整数
- 列表是固定的。没有插入或删除
一种方法是创建一个数组并索引到该数组。这可能不节省空间。我可以使用无序映射吗?我应该定义什么散列函数?
// Sort in reverse order to aid the lookup process
vector<unsigned int> sortedByRange;
//... sortedByRange.push_back(..)
sort(sortedByRange.begin(), sortedByRange.end(), greater);
Range = (sortedByAddress_.begin() - sortedByRange.end();
std::cout<<"Range :"<<Range<<std::endl; //prints 3330203948
std::pair<unsigned int, unsigned int> lookup(unsigned int addr){
pair<unsigned int, unsigned int> result;
vector<unsigned int>::iterator it = lower_bound(sortedByRange.begin(),
sortedByRange.end(), addr);
result.first = *it;
result.second = *(it++);
return result;
}
如果总范围不是很大,你可以构建一个任意大小的采样索引数组(你想向它扔多少RAM?)
因此,例如,如果数据的总范围是256M,并且您有一个备用兆字节,那么您将存储数据范围中每1K间隔的位置。然后,对于任何给定的数据点,您对索引数组进行O(1)(实际上是O(2):))探测,以找到该数据点的最低和最高合理范围,然后您可以仅对该范围进行lowest_bound。如果你的范围在大小上没有很大的变化,那么你应该可以得到平均的恒定时间查找。
如果你不想在这个问题上投入那么多内存,你可以尝试基于平均范围大小和模糊因子的两个线性估计。如果结果不包含特定的数据点,您可以返回到完整的二进制搜索;否则,同样,在限制范围内的二进制搜索应该是平均线性时间。
这是第一个建议,以防手工不够清晰。完全未经测试的代码,甚至没有尝试编译它,而且整数类型的使用也很草率。如果你用它,试着让它更漂亮。此外,我应该(但没有)将索引范围的开始限制为*begin_;如果它明显大于0,你应该修复它。
// The provided range must be sorted, and value_type must be arithmetic.
template<type RandomIterator, unsigned long size>
class IndexedLookup {
public:
using value_type = typename RandomIterator::value_type;
IndexedLookup(RandomIterator begin, RandomIterator end)
: begin_(begin),
end_(end),
delta_(*(end_ - 1) / size) {
for (unsigned long i = 0; i < size; ++i)
index_[i] = std::lower_bound(begin_, end_, i * delta_) - begin_;
// The above expression cannot be out of range
index_[size] = end_ - begin_;
}
RandomIterator lookup(value_type needle) {
int low = needle / delta_;
return std::lower_bound(index_[begin_ + low],
index_[begin_ + low + 1],
needle);
}
private:
RandomIterator begin_, end_;
value_type delta_;
std::array<int, size + 1> index_;
}
方法1:如果您只需要知道给定的数字是否在列表中,并且最大值不太大,可以考虑使用位字段。那么查找将是O(1)运算。
方法2:如果值的范围很大(其中有小整数和大整数),但列表大小不大(例如几千),您可以尝试(通过编程)制作一个
- 对列表中的值是一对一的
- 将给出范围为
0
。。。CCD_ 2和CCD_ - 计算起来相对便宜
然后可以将常量列表的值放入一个数组中,并根据哈希值进行索引,以便快速检查给定输入值的包含情况。如果列表中有孔(m
非零),则应使用特殊值(例如-1
)指示这些孔。
包容性测试:针对给定的输入1.计算哈希值;2.如果哈希值的值超出范围,则该输入不在列表中;3.否则,当且仅当由哈希值索引的生成数组中的值与输入值相同时,输入属于列表。
在SO中,如何制作哈希函数值得另一个问题(对于字符串值,有工具可以生成用于此目的的工具)。:-)
限制:如果列表不是在编译时创建的,而是在程序运行时计算或接收的,则此方法不适用。此外,如果这个列表经常更改,那么生成哈希函数和代码所需的计算时间可能会使这种方法不合适。
Javascript
let searchRangeInterger = function(nums, target) {
let res = [-1, -1];
let leftSide = find(nums, target, true);
let rightSide = find(nums, target, false);
if (!nums.length) return res;
if (leftSide > rightSide) return res;
return [leftSide, rightSide];
};
let find = function (nums, target, findLeft) {
var left = 0;
var right = nums.length - 1;
var mid = 0;
while (left <= right) {
mid = Math.floor((left + right) / 2);
if (nums[mid] > target || (findLeft && nums[mid] === target)) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return findLeft ? left : right;
};
- 如何反转整数参数包
- enum是C++中的宏变量还是整数变量
- 努力将整数转换为链表。不知道我在这里做错了什么
- 整数不会重复超过随机数
- 在C++中手动调整数组大小
- 如何使用 binary_search STL 函数在嵌套类中搜索整数?
- 查找存储在二叉搜索树的所有非叶子中的数据总和?(返回整数的独立递归函数
- 从整数向量向量搜索整数向量的最佳算法
- 有序地图字符串搜索与整数搜索之间的时间复杂度
- 比较/搜索数组中多个整数的最佳解决方案
- 超快速搜索整数子字符串的方法
- 从一系列整数中搜索
- 要求用户在数组中搜索一个整数
- C++:二叉搜索树适用于整数,但当我尝试传递字符串时崩溃
- C++如何在文本文件中搜索特定整数的出现次数
- 在C++中,从已排序的整数向量中搜索和删除元素的最快方法
- 使用整数列表文档进行全文搜索的最佳方法
- 在搜索大质数时,整数常数对于' long '类型来说太大
- 如何使字符串和整数作为二进制搜索树中的参数
- 在c++中对整数数组进行线性搜索时,SSE比较不能按预期工作