尚不清楚您想要的所有行为和约束是什么。例如,按照您列出的示例过滤器从左到右的顺序,过滤器是否可以包含“”(您的匹配所有“通配符”),然后是另一个非“”字符串?
无论如何,假设您不允许允许过滤器有一个"" 通配符后跟一个非"" 术语,您可以创建一个类型为...的过滤器索引...
std::unordered_map<std::string,
std::variant<filter*,
std::unordered_map<std::string,
std::variant<filter*,
std::unordered_map<std::string,
std::variant<filter*,
std::unordered_map<std::string,
std::variant<filter*,
std::unordered_map<std::string, filter*>
> > > > > > > > index;
这有效地描述了一个树,其中每个级别可能有一个精确的字符串匹配或一个"" 通配符过滤器匹配,如果这是过滤器中最后一个非"" 术语,则为匹配的过滤器产生一个filter* ,或索引的下一级。
鉴于您的过滤候选对象v1,并假设您已经完成了填充索引的明显工作,您可以像这样进行搜索:
std::vector<filter*>
match(const std::array<string, 5>& v,
const auto& index) {
std::vector<filter*> matches;
auto it0 = index.find("");
if (it0 != index.end())
matches.push_back(std::get<filter*>(*it0)); // match-everything filter
if ((it0 = index.find(v[0])) == index.end())
return matches; // no non-wildcard match
const auto& i1 = std::get<1>(*it0); // next level in index
auto it1 = i1.find("");
...same kind of logic, working your way through the 5 levels...
这涉及最多 10 个哈希表查找,因此 O(1) w.r.t。过滤器集的大小。
这并不一定意味着它是任何给定数据的最佳性能选择:字符串的典型长度、其中的模式,例如可能以相同的字符开头并且仅在最后一个不同几个字符,过滤器集的长度 - 了解这些内容可能会建议一种实际上更快的方法。
哈希表的工作情况还取决于所使用的哈希函数。对于较长的字符串,GCC 的字符串哈希函数 - MURMUR32 - 比 Visual C++ 的质量要高得多(为了提高速度,它只包含沿字符串间隔的 10 个字符),并且 GCC 使用质数桶计数,这比 Visual C++ 的功能更不容易发生冲突 - of-2 选择。其他优化可以通过对数据的了解来建议,例如如果您知道字符串总是