假设我有2个相等长度的字符串。我正在寻找一个度量来衡量两个字符串在它们都具有大小> = 2的子序列数量方面密切相关的程度。
例如,假设x="ABCDEF"
和y="DEFABC"
。在这两个字符串中,子序列"ABC"
,"DEF"
,"AB"
,"BC"
,"DE"
,"EF"
都是内部子序列{ {1}}并出现在两个字符串中。
是否有任何度量标准或非天真算法可以衡量这些模式中有多少出现在两个字符串中?
答案 0 :(得分:2)
您可以尝试使用后缀树 / 后缀数组。
https://en.wikipedia.org/wiki/Suffix_array
https://en.wikipedia.org/wiki/Suffix_tree
对于后缀数组实现中问题中提供的示例,您将拥有
ABCDEF -> $
ABCDEF$
BCDEF$
CDEF$
DEF$
EF$
F$
($ marks end of string)
后缀数组,允许您将二进制搜索用于其他字符串 n-gram 。让我们在后缀数组上测试"DEFABC"
的n-gram:
"DE" - found (DEF$), countinue to longer n-gram (3-gram)
"DEF" - found (DEF$), countinue to longer n-gram (4-gram)
"DEFA" - failed, continue to next 2-gram
"EF" - found (EF$), countinue to longer n-gram (3-gram)
"EFA" - failed, continue to next 2-gram
"FA" - failed, continue to next 2-gram
"AB" - found (ABCDEF$), countinue to longer n-gram (3-gram)
"ABC" - found (ABCDEF$), end of string reached, continue to next 2-gram
"BC" - found (BCDEF$), end of string reached
找到 6
常见 n-gram (n >= 2
)。
到目前为止,我们花了N
来创建后缀数组和O(N*log(N))
来扫描 n-gram (O(N*log(N))
扫描,O(N)
查看后缀数组); 后缀树更难实现,只需创建O(log(N))
即可。
一般情况下,检查大小为O(N)
和M
的字符串时,如果后缀数组和{{1},则复杂度为N
在后缀树的情况下。
示例 C#代码
O(M*log(M) + N*log(M))
答案 1 :(得分:1)
有简单的O(n ^ 3)解决方案,首先为每个字符串提取所有序列并使用3个嵌套循环i(1..n)j(1..i)k存储它们(例如在地图内) (j..i)并确保每个序列的长度> = 2,现在迭代2个存储的序列并计算发生的数量。
<强> UPD 强>
这是一个伪Java代码:
char[] s1 = next().toCharArray();
HashMap<String,Integer> map1 = new HashMap<>();
for(int i=0;i<s1.length;i++)
for(int j=0;j<=i;j++)
if(i-j>=2) {
String sub = "";
for(int k=j;k<=i;k++)
sub+=s1[k]; // Instead use String builder to concat 2 strings because concating using String class in Java is O(n)
if(map1.get(sub) == null)
map1.put(sub,0);
map1.put(sub,map1.get(sub)+1);
}
for(String sub:map1.keySet())
out.println(sub + " " +map1.get(sub));
对2字符串执行相同操作并计算发生的次数。