两个单词之间的最短编辑次数


11

我正在寻找一种数据结构和一种算法来计算将一个单词转换为另一个单词所需的最小更改数量,假设两个单词作为输入,其中唯一允许的更改是

  • 在其中一个末端添加一个字母(例如AB-> ABC),
  • 复制并连接整个单词(例如,ABC-> ABCABC),
  • 切成两个词(重复动作的对偶,ABCABC-> ABC + ABC),
  • 删除字母之一(例如,ABC-> AC),然后
  • 重复字母之一(例如,ABC-> ABBC)。

例如,从ABC到BCBC的最小移动顺序是ABC-> BC(删除A)-> BCBC(重复)。

我没有计算机科学背景。也许这是一个众所周知的问题,但是我的Google搜索没有给我任何帮助。

您知道一些相关的,定义明确的问题吗?

编辑:正如安东尼·拉巴雷(Anthony Labarre)的答案所建议的那样,我阅读了一些有关摆球置换/排列问题的论文,该问题与上述问题相似。有人知道这个问题吗?这相关吗?


1
大概在en.wikipedia.org/wiki/String_metric列表中没有一个适用,在sourceforge.net/projects/simmetrics中也不适用吗?
2013年

我不了解所有这些方法,但是这些方法的大多数目标是对齐字符串,只允许更改单个字母且不允许进行更复杂的移动。
cz3rk 2013年

1
复制适用于整个字符串ABC-> ABCABC,因此方向无关紧要。但是,重复的方向只能像结结巴巴那样从左到右。
cz3rk

2
如果输入的单词不共享字母为什么会很重要?(@reinerpost的序列之间A和之间应该有一个空字符串B。)
Jeffε13年

2
www

Answers:


3

我不知道是否已经研究了这个确切的问题,但是 Chaudhuri等人。研究了相关的串联复制-随机丢失问题:给了您一个置换,您想通过以下方式将其转换为身份置换:(1)复制任意长度的片段,然后将副本附加在原始副本之后,然后(2)删除元素,以便您获得新的排列而不是字符串。请注意,先应用(1),再应用(2),即可完成一项操作。

可以根据赋予每个操作的权重来定义不同的变体,权重在其论文中取决于重复段的宽度。他们还研究了与全基因组复制相似的问题,这正是您所允许的复制类型。我不记得在字符串上下文中阅读过有关此问题的文章,但是我希望这至少可以为您提供一个搜索起点。


谢谢,我将看看他们的工作。我可以看到两个问题之间的关系。
cz3rk

2

正如已经指出的那样,该问题类似于更常见的编辑距离问题(位于Levenshtein距离的下方)。它还具有例如动态时间规整距离(在您的最后一个需求中重复或“停顿”)的共性。

迈向动态编程的步骤

x=x1xny=y1ymd(x,y)

min{d(x,y1ym1)+1▻ Add letter at endd(x,y2ym)+1▻ Add letter at beginningd(x,y1ym/2)+1if y=y1ym/2y1ym/2▻ Doublingd(x1xn/2,y)+1if x=x1xn/2x1xn/2▻ Halvingd(x1xn,y)+1▻ Deletiond(x1xn1,y1ym1)if yn=ym▻ Ignoring last elt.

在这里,最后一个选项基本上说将FOOX转换为BARX等效于将FOO转换为BAR。这意味着您可以使用“末尾添加字母”选项来实现口吃(重复)效果和一点删除。问题是,它会自动让你添加一个任意的字符串中间性格,以及,你可能不想要的东西。(这种“忽略相同的最后一个元素”是在任意位置实现删除和口吃的标准方法。它的确禁止了任意插入,同时允许在任一端进行添加,但是有些棘手……)

我已经包括了此故障,即使它不能完全完成工作,以防万一其他人可以某种方式“营救”该故障,也因为我在下面的启发式解决方案中使用了它。

(当然,如果您得到这样的细分,实际上定义了您的距离,则只需添加备注即可,并且您将找到解决方案。但是,因为您不仅在处理前缀,所以我不会认为您可以只使用索引进行记忆;您可能必须为每个调用存储实际的,经过修改的字符串,如果您的字符串大小足够大,它将变得很大。)

迈向启发式解决方案

另一种方法可能更容易理解,并且可以使用更少的空间,它是使用算法(从基本上,最好是首先分支定界)。搜索空间将直接由您的编辑操作定义。现在,对于一个大字符串,您A得到一个较大的邻居,因为您可以删除任何字符(为每个可能的删除操作给您一个邻居),或复制任何字符(再次为您提供线性数量的邻居),以及在任一端添加任何字符,这将给您的邻居数量等于字母大小的两倍。(只希望您不使用完整的Unicode ;-)使用如此大的扇出功能,您可以使用双向 或一些相对的A来实现相当大的加速。

为了使起作用,您需要为到目标的剩余距离设置一个下限。我不确定这里是否有明显的选择,但是您可以做的是根据我上面给出的递归分解实现一个动态编程解决方案(如果字符串很长,还会出现空间问题)。尽管该分解不能完全计算出您的距离,但可以保证它一个下界(因为它更宽松),这意味着它将在用作启发式方法。(我不知道它有多紧,但这是正确的。)当然,绑定函数的备注可以在期间的所有绑定计算中共享AAA跑。(在那里进行时间/空间折衷。)

所以…

我提出的解决方案的效率似乎在(1)字符串的长度和(2)字母表的大小上花了很多时间。如果两者都不大,则可能有效。那是:

  • 使用我的递归分解和动态编程(例如,使用记忆的递归函数)来实现距离的下限。
  • 通过状态空间中的“动作”以及基于动态编程的下限,将编辑操作实现为(或双向)。AA

我不能真的保证效率如何,但是应该是正确的,并且它可能比暴力解决方案要好得多。

如果没有别的,我希望这会给您一些进一步调查的想法。


0

一些相关的,定义明确的问题将是序列比对的问题。这是不同的,因为它不使用复制操作。定义的操作是:字符插入,字符删除,字符转换。解决此问题的常用算法是Needleman-Wunsch


我知道这一点,但我真的想使用一组定义好的动作。我发现做到这一点的唯一方法是使用蛮力递归算法。不太好,如果单词的大小增加,他可能会变得计算量很大。
cz3rk

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.