字符串距离,仅限换位

时间:2011-10-25 18:55:43

标签: string algorithm dynamic-programming levenshtein-distance edit-distance

  

可能重复:
  Counting the swaps required to convert one permutation into another

我正在寻找一种计算某种字符串距离的算法,其中只允许操作是两个相邻字符的转置。例如:
string1:“妈妈”
string2:“moterh”
距离:2(首先交换“h”和“e”并获得“motehr”然后“h”和“r”导致“moterh”)
我知道Damerau-Levenshtein的距离与这个问题非常相似,但它需要大量的内存(我希望它可以在高达1 000 000个字符的单词上工作得非常快)。我已经写过:

int amo = 0;

for (int i = 0; i < n; i++)
{
    if (fromString[i] == toString[i])
        continue;
    char toWhat = toString[i];
    int where = -1;
    for (int j = i; j < n; j++)
    {
        if (fromString[j] == toWhat)
        {
            where = j;
            break;
        }
    }
    while (where != i)
    {
        char temp = fromString[where];
        fromString[where] = fromString[where - 1];
        fromString[where - 1] = temp;
        where--;
        amo++;
    }
}
cout << amo << endl;`

字符串表示为char [n],其中n是它们的长度。我很确定有一种方法可以更快地完成它,如果有人会告诉我如何操作或编写一些源代码(最好的是Java / Python / C ++,但任何事情都很棒)我会非常感激。

P.S。对不起任何语言错误,我不是英语,我还没有掌握那种语言。

1 个答案:

答案 0 :(得分:5)

基本上你要求edit distance算法,但只允许换位(a.k.a.交换,twiddling)操作。在“算法简介”一书中,您将找到实现旋转操作的线索,这是动态编程章节末尾的问题之一。此外,在“算法设计手册”一书中,在动态编程一章中,C语言编辑距离算法的完整实现 - 转换操作(同样,它是本章末尾提出的练习之一) )。

在上面的链接中,您会发现实现编辑距离算法的典型方法是使用动态编程,其成本为O(mn)时间和O(mn)空间。据我所知,没有办法更快地完成它(例如在不到O(mn)的时间内),但肯定你可以在更小的空间内完成 - 聪明,你可以将空间减少到O(m),给定只需要表中当前行和前两行来计算转置操作的成本。

也就是说,假设您只需要编辑距离。如果您需要实际的编辑操作,那么您将使用O(mn)空间来重建解决方案 if 使用动态编程。但是,您可以使用Hirschberg's algorithm将空间缩小为O(min {m,n})重建实际的编辑操作。