Algorithm 对于无序序列匹配问题,哪种算法更好?
如果我有两个序列(例如字符串) 我想知道从b到a的最佳子串匹配(无序),例如:Algorithm 对于无序序列匹配问题,哪种算法更好?,algorithm,sequence,matching,Algorithm,Sequence,Matching,如果我有两个序列(例如字符串) 我想知道从b到a的最佳子串匹配(无序),例如: optimal (6 matched parts, 19 characters of a matched) b a DDFF -> DDFF (4,7) AA -> AA (0,1) 1122 -> 1122 (11,14) 1 D -> D (21) HH VV1VAA -> VV1VAA
optimal (6 matched parts, 19 characters of a matched)
b a
DDFF -> DDFF (4,7)
AA -> AA (0,1)
1122 -> 1122 (11,14)
1
D -> D (21)
HH
VV1VAA -> VV1VAA (15,20)
FE -> FE (8,9)
还有另一种解决方案,但不是最优的:
not optimal (8 parts matched, 19 characters of a matched)
b a
DDFF -> DDFF (4,7)
AA -> AA (0,1)
1122 -> 1122 (11,14)
1 -> 1 (17)
D -> D (21)
HH
VV -> VV (15,16)
1
VAA -> VAA (18,20)
FE -> FE (8,9)
什么样的算法更适合这个问题???(我需要最佳结果,性能至关重要)
谢谢。有趣的问题,您可以使用Boyer-Moore(–Moore|u string|u search|算法)或KMP(–Morris–Pratt|u算法)或任何其他线性时间字符串搜索算法,用O(|a|b |+b| 2)来解决它
- 对于每个b[0..i]ty,在字符串a中找到它(在O(|a |+i)中),直到你再也找不到它为止
- 你知道你可以找到b[0..i],但不能找到b[0..i+1],所以你有一个匹配的b[0..i],然后继续b[i+1..i+1],b[i+1..i+2]
- 在结束时,b的每个部分是否匹配,如果匹配,则尽可能大
关于最佳解决方案的思考:
- 对于| b |的每一个| b | ^2子串,确定它是否可以在| a |中找到,并只保留它所对应的子串
- 我们需要在这些字符串中找到一个子集,其中包含:
- 它们之间没有重叠
- 长度之和最大
- 长度相等时,字符串的数量必须最小
您可能需要寻找近似算法……如果我理解您的问题,您需要找到一组由两个给定字符串组成的非重叠公共子字符串,它们要么使公共子字符串的总长度最大化,要么使公共子字符串的数量最小化。我将提出以下启发式方法:找到两个字符串中最长的公共子字符串(LCS),删除它,然后重复。我不能证明这是最优的,但我有一个非常有效的算法 在你的例子中 AAACDDFFFEE11122VV1VAADD DDFFAA1121DHHV1VAAFE LCS=VV1VAA AAACDDFFFEE1122DD DDFFAA1121DHHFE LCS=DDFF AAACFEE1122DD AA11221DHHFE LCS=1122 AAACFEEDD 阿赫菲 诸如此类 算法如下 1) 使用基于后缀树的标准LCS算法 1.1构建两个串联字符串的后缀树,并使用唯一的终止符 1.2根据根植于其中的子树是否具有来自其中一个或两个字符串的叶子,用1,2或两者标记每个节点 1.3计算每个节点的管柱深度 1.4查找标记为1和2的字符串最深节点 2) 删除以该节点为根的子树,并更新其上节点的标签 3) 从1.4开始重复 当树没有标记为1和2的节点时,算法终止 1.1可在与两个字符串长度之和成比例的时间内完成 1.2、1.3和1.4只不过是树遍历 2如果正确实现了树,并且更新受LCS长度的限制,则移除时间应为常数 3又是一棵树的遍历,但它是一棵较小的树的遍历 这是一个优化,为了避免重复的树遍历,让我们添加步骤1.35:按字符串深度对具有两个标签的内部节点进行排序(在单独的数据结构中,树仍然存在)。现在可以扫描已排序的节点列表,执行2)并重复。有了这个优化,如果你能使用基数排序,它看起来像是线性时间的算法,你不能在一个渐进的意义上击败它
我希望这是正确的和足够清楚的,我相信你需要熟悉一下后缀树文献,然后它听起来很明显。我推荐丹·古斯菲尔德(Dan Gusfield)的《字符串、树和序列算法》(Algorithms on String,Trees and Sequences)一书,特别是第7.4节,如果您有问题,请告诉我。您能重新表述您的问题吗?我知道a和b是问题输入的一部分(“从b到a无序匹配的最佳子字符串”),但子字符串也是输入的一部分吗?或者您正在寻找最长的(或任何)公共子序列?无需其他输入。LCS不是我想要的。在本例中,LCS将输出“DDFF1122VVVA”,b中的“AA”和“FE”将不属于LCS,因为LCS是订单问题。谢谢。我需要这个问题的最优解(我将我的问题改为更清楚地描述),重复子串搜索算法不会得到最优解。事实上,在第一个例子中,最优性问题并不清楚,我现在更明白了。我的(贪婪)方法在匹配字符总数上是最优的,但可能比“最优”方法有更多的部分。在问题陈述中,我仍然只看到两个例子。要求定义解决方案的总顺序是不是太过分了?匹配的字符数是否总是比部件总数更重要?如果你不清楚地定义这一点,就会有一些琐碎的解决方案(一个是将字符串视为多个字符集并输出交集,另一个极端是最长的公共子字符串)@piccolbo我想他想要的是最大化匹配字符的数量(多个字符集将给出该数量),在所有解决方案中
not optimal (8 parts matched, 19 characters of a matched)
b a
DDFF -> DDFF (4,7)
AA -> AA (0,1)
1122 -> 1122 (11,14)
1 -> 1 (17)
D -> D (21)
HH
VV -> VV (15,16)
1
VAA -> VAA (18,20)
FE -> FE (8,9)