【问题标题】:Find super-string in a set of strings在一组字符串中查找超字符串
【发布时间】:2020-05-05 13:20:00
【问题描述】:

我有一个字符串列表,例如:

cargo
cargo pants
cargo pants men buy
cargo pants men
cargo pants men melbourne buy

在此,包含所有剩余字符串的字符串是cargo pants men melbourne buy。我想删除所有较短的字符串,只保留最长的“超级字符串”。

注意,如果cargo pantscargo shorts存在2个查询,它们将被视为2个不同的查询,不会合并。

到目前为止,我一直在以蛮力的方式执行此操作 - 从集合中选择一个字符串并遍历同一集合,删除所有其他作为当前字符串“子字符串”的字符串。大概,

for (String p: big_set) {
    for (String q: big_set) {
        if (!p.equals(q)) {
            if (has_all_words(p, q)) { /* If all words in 'p' is also in 'q' */
                big_set.remove(p);
                break;
            }
        }
    }
}

是否有一种智能算法可以在少于 O(n^2) 的时间内完成此操作?在此函数中,has_all_words 将在比较时保留单词的顺序。

出于好奇,我有数十亿个搜索查询的庞大列表(例如发送到 Google/Yahoo/Bing 的查询),我正在尝试为这些查询找到上位词。有一个服务器可以解析这个字符串并生成各种有趣的类别。我正在尝试压缩查询列表,以期最小化计算成本和带宽。这种方法肯定会显着减少带宽(因为人类不能一口气想到buy cargo pants melbourne),但预计算成本高得令人望而却步。所以我一直在寻找可以做到这一点的算法,但我还没有遇到任何可以做到这一点的算法。

【问题讨论】:

  • 但是"cargo pants men melbourne buy".contains("cargo pants men buy") 返回false...
  • @Andronicus 但它包含每个单词
  • 这不是您首先要检查和指定的内容
  • 我不确定您要达到的目标。如果有一个词在其中一个查询中,但在另一个查询中没有怎么办?如果你有["foo bar", "foo baz"]。您的预期输出是什么?
  • @Andronicus - 我已经更正了算法以避免混淆。对不起这是我的错。此外,这只是一个粗略的工作。不是为了规模。原始代码是用 C 语言编写的,以 kyotocabinet 作为支持集。 Java 在这里,因为它是一种可爱的语言。

标签: java string algorithm collections


【解决方案1】:
  • 我想你想要的只是删除所有这些子字符串 可以在超级字符串中找到。就像 ["foo bar", "foo baz"] 你必须存储两个字符串。

  • 如果我的猜测是正确的,那么您可以在少于 O(n^2) 的时间内实现它。 在从任何短的每个超级字符串开始之前按字母顺序 这样就不会像货物裤子裤子货物男人买这样的情况了

  • 首先,根据那里的降序对字符串进行排序
    长度。 然后拿起最长字符串的子字符串(就像我们一样
    从第一个索引迭代并以相反的顺序排序)和
    开始在其余字符串中搜索它。

  • 如果找到字符串将其删除,并且一旦搜索并删除 完成只是用下一个子字符串再次迭代 包含最后一个子字符串的相同超级字符串。

  • 最后,您将只剩下唯一的字符串(如果 您将 ["foo bar", "foo baz"] 视为唯一字符串。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-19
    • 1970-01-01
    • 2011-01-11
    • 2017-03-22
    • 2015-08-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多