根据唯一的子串将字符串对

时间:2012-03-06 22:17:42

标签: java string-matching

我有两组字符串,如果可能的话,我需要匹配每对中的相同子字符串(下面的示例中的粗体文本;粗体/大写仅在此处执行以强调没有办法通过查找来识别键子字符串在每个列表中唯一的列表元素)。文本的剩余部分(lorem ipsum)可能是许多元素共有的,也可能是完全唯一的。

列出一个:

  1. “Lorem ipsum dolor sit amet, CANDY BAR consectetur adipisicing elit,“
  2. “sed do eiusmod CANDY CANE tempor incididunt ut labore et dolore 麦格纳“
  3. “sed do eiusmod tempor HOMER incididunt ut labore et dolore 麦格纳“
  4. “Lorem ipsum dolor sit amet,consectetur adipisicing PICKUP 卡车 elit,“
  5. “ullamco laboris nisi ut aliquip ex ea commodo consequat.Duis aute”
  6. 列表二:

    1. “sed do eiusmod tempor incididunt HOMER ut labore et dolore magna”
    2. “aliqua。使用adim veniam, CANDY BAR quis nostrud exercitation”
    3. “aliqua。使用adim veniam,quis nostrud CANDY CANE 练习”
    4. “irure dolor in repreptderit in voluptate velit esse cillum dolore”
    5. “Lorem ipsum dolor sit amet,consectetur adipisicing PICKUP TRUCK elit,”
    6. 下面的示例文本匹配为:1-2; 2-3; 3-1; 4-5

      列表1中的元素5和列表2中的元素4与任何内容都不匹配。

2 个答案:

答案 0 :(得分:2)

如果您要处理的数据总量相对较小,则已建议的解决方案(使用.contains()或正则表达式)可能是最实用的。 当数据量更大时,以下是一种方法。

解决方案的关键部分是使用后缀数组。后缀数组是文本中所有后缀(在字符串结尾,而不是语言后缀的意义上)的按字典顺序排序的列表(或多个文本的串联)。

在您所描述的示例中,这将涉及仅构建两个集合的连接文本的后缀数组。我假设我们为 set 2 执行此操作,因此我们将使用唯一的分隔字符连接所有句子(我已选择下面的哈希字符#):

 sed do eiusmod tempor incididunt HOMER ut labore et dolore magna#aliqua. Ut enim ad minim veniam, CANDY BAR quis nostrud exercitation#aliqua. Ut enim ad minim veniam, quis nostrud CANDY CANE exercitation#....

接下来,您将构建该字符串的后缀数组,以及最长公共前缀数组(LCP)。这两个数据结构都可以使用如果文本量不是非常大,则使用强力方法。或者,有一些库可以更有效地构建它们,例如jSuffixArrays

最后你遍历 set 1 的句子,并在每个句子中通过相关标记的候选起始位置(可能只有跟随空格或标点符号的单词)并搜索集合的后缀数组2为他们。当LCP阵列可用时,搜索后缀数组可以在O(n + m)时间内完成(n是第2组连接字符串的长度,m是候选字符串的长度你正在寻找)使用classical search algorithm by Manber and Myers,但如果仍然太慢,有可用的精炼方法,例如由Navarro and Mäkinen 2007描述。

对于您找到的每个匹配,后缀数组可以很容易地提供有关字符串在第2组中出现的频率以及有多少不同句子的信息。如果需要,我可以详细说明如何在编辑这篇文章时做后者。

答案 1 :(得分:1)

据我所知,你有一个在每个列表中都是唯一的字符串列表。这些字符串是列表中字符串的一部分(子字符串)。我会创建一个这样的子串的列表,然后使用正则表达式进行比较(而不是在这种情况下你需要知道起始索引的java子串)。