在子字符串数组中高效地查找字符串

C++: find a string in an array of sub-string efficiently

本文关键字:字符串 查找 高效 数组      更新时间:2023-10-16

我有一个字符串前缀数组:std::vector<std::string> haystack = {"/bin/", "/usr/bin/", "/usr/local/bin/"} .

是否有一种有效的方法来发现std::string needle = "/bin/echo"haystack的子字符串开始,使用标准c++库?

如果我需要找到确切的匹配,我可以使用std::set<std::string>,它将执行有效的二进制搜索,但是我只需要匹配字符串的第一部分,所以目前我正在使用一个简单的循环:

for (auto it = haystack.begin(); it != haystack.end(); it++) {
    if (needle.compare(0, it->size(), *it) == 0) {
        return true; // Found it
    }
}
return false;

我要添加的一个"优化"是,如果您使用std::any_of,它将在找到第一个子字符串匹配时短路

auto found = std::any_of(begin(haystack),
                         end(haystack),
                         [&needle](std::string const& sub)
                         { 
                             return needle.compare(0, sub.size(), sub) == 0;
                         });

如果你想找到匹配的子字符串,你可以使用std::find_if,它也会在找到第一个匹配时短路。

auto match = std::find_if(begin(haystack),
                          end(haystack),
                          [&needle](std::string const& sub)
                          { 
                              return needle.compare(0, sub.size(), sub) == 0;
                          });
  1. 按字符串长度降序排序hasystack
  2. 按此顺序比较不超过needle的前缀;从右到左。例如,如果prefix是5个字符长,比较prefix[4]needle[4],然后比较prefix[3]needle[3],以此类推。

这样,您将立即丢弃许多不匹配项。作为奖励,您将首先找到最长的匹配(可能正是您想要的)。