我有一个通过ifstream
从文件加载的字符串向量,它不需要是一个向量,但它看起来像这样:
std::vector<std::string> data;
data.push_back("CONSISTENTTEXT:variabletext1");
data.push_back("CONSISTENTTEXT:variabletext2");
// 100,000 + more push_back's
因为它是一个大向量,我需要循环查找搜索字符串的所有引用我想知道如何做最有效的字符串不区分大小写的给定我可以忽略字符串的前15个字符?
答案 0 :(得分:1)
首先要尝试的是显而易见的:
std::copy_if(data.begin(), data.end(), output,
[&searchForMe](std::string const& str) {
return caseInsensitiveEquals(
std::string_view{str}.remove_prefix(15),
std::string_view{searchForMe}.remove_prefix(15));
});
请参阅std::copy_if
和std::string_view::remove_prefix
您甚至可能只想在将其添加到data
之前删除前缀。这将大大减少您的内存使用量,并可能使您的字符串适合小字符串优化大小。搜索将非常简单:
std::copy_if(data.begin(), data.end(), output,
[&searchForMe](std::string const& str) { // maybe `std::string_view str`
return caseInsensitiveEquals(str, searchForMe);
});
如果这不够快(可能因为矢量很大而不够快),有一些选择。你总是可以找到Execution Policies,但它们无助于减少需要完成的工作量。
我要考虑的下一件事是std::equal_range
,这需要对数据进行排序:
// assuming you removed all the prefixes
std::sort(data.begin(), data.end(), caseInsensitiveLessThan);
auto rangePair = std::equal_range(data.begin(), data.end(), searchForMe, caseInsensitiveLessThan);
O(n log n)
排序后,查找为O(log n)
。
如果这仍然不够快,或者您可能无法支付某种费用,则需要专门的数据结构。您可能可以使用std::unordered_multiset<std::string, CaseInsensitiveHash, CaseInsensitiveEquals>
。