如何检查是否存在具有相同前缀的双关键字

How to check whether there is a two key with the same prefix?

本文关键字:前缀 关键字 存在 何检查 检查 是否      更新时间:2023-10-16

有这样的地图:

typedef std::string Path; // has this format "/<a>/<b>/<c>"
typedef std::vector<std::string>               Paths;
typedef std::map<std::string, Paths>           PathMapping;
PathMapping mathMapping; // ( "/a/b/c" --> "/a/b/c1", "a/b/c2" )
                            ( "/a/b/d" --> "/a/b/d1", "a/b/d2" )
                            ("/a/b/c/d" --> "a/b/c/d1", "a/b/c/d2" ) // not allowed

如何检查映射中是否有其他键的子字符串键?

map中的密钥按字典顺序排序,因此,如果一个密钥A将成为另一个密钥B的前缀,则:

  • AB之前
  • A也是AB之间的任何密钥的前缀

因此,我们可以在地图中进行简单的扫描(此处为m):

auto current = m.begin();
for (auto it = next(current), end = m.end(); it != end; ++it ) {
    // Note: if current is not a prefix of "it", then it cannot be a prefix
    // of any key that comes after "it", however of course "it" could
    // be such a prefix.
    // current is not a prefix of "it" if "it" is shorter
    if (it->first.size() <= current->first.size()) { current = it; continue; }
    // current is not a prefix of "it"
    if (it->first.substr(0, current->first.size()) != current->first) {
        current = it; continue;
    }
    // current is a prefix
    std::cout << "'" << current->first << "' is a prefix of '" << it->first << "'n";
}

注意:计算子字符串是不必要的,不分配的starts_with函数会更好,但它确实能理解这一点

你可以在这里查看完整的代码。

不更改数据结构:

for (const auto& p : mathMapping)
    for (const auto& s : mathMapping)
        if (starts_with(p.first, s.first))
            // collision

它的C++03版本是:

for (PathMapping::const_iterator p = mathMapping.begin(); p != mathMapping.end(); ++p)
    for (PathMapping::const_iterator s = mathMapping.begin(); s != mathMapping.end(); ++s)
        if (starts_with(p->first, s->first))
            // collision

其中CCD_ 11是这里提出的函数之一。

但如果您可以更改数据结构,我会用/分割每个段,并使用树状容器。