python - 使用尽可能少的步骤转换序列

标签 python algorithm levenshtein-distance constraint-programming register-allocation

我的问题是,我应该用什么算法来实现一个功能 translate 根据以下 Python 示例工作:

>>> translate('aa', 'a')
[('S', -1)]
>>> translate('a', 'aa')
[('R', 0, 'x'), ('S', 1), ('W', 0, 'x')]
>>> translate('abc', bca')
[('R', 0, 'x'), ('R', 1, 'y'), ('R', 2, 'z'),
 ('W', 2, 'x'), ('W', 0, 'y'), ('W', 1, 'z')]
>>> translate('abc', 'cabc')
[('R', 2, 'x'), ('S', 1), ('W', 0, 'x')]
>>> translate('ab', 'bab')
[('R', 1, 'x'), ('S', 1), ('W', 0, 'x')]
>>> translate('abc', 'bcabc')
[('R', 1, 'x'), ('R', 2, 'y'), ('S', 2), ('W', 0, 'x'), ('W', 1, 'y')]

这是与生成最佳代码相关的问题的概括 在我拥有的编译器中。该算法是我所追求的,所以 解决方案不一定必须在 Python 中。在“现实”中 变量(上面的'x', 'y' and 'z')是机器寄存器 和字符串索引堆栈位置。

从示例中可以看出,该算法是关于转换 使用最少的从一个字符序列到另一个字符序列的字符串 步骤数。需要注意的是只有三种可能 可供选择的操作:

  1. 将字符串向左或向右移动 N 步。如果它是 向右移动,引入的新指数充满了 ? 个字符。例如 ('S', 2) -- 将字符串移动两个索引 权利。
  2. 将索引处的字符读入变量。这个操作不能 如果字符串中有任何 ? 字符则执行。例如 ('R', 4, 'q') -- 读取索引 4 处的字符并将其存储在 变量 q.
  3. 将变量中的字符写入目标字符串的索引中。这 索引必须在范围内。例如 ('W', 1, 'q') -- 将字符写入 字符串中索引 0 处的变量 q

这是实现这些操作的简单 Python 代码和一个 从 abbab 的转换示例 手动执行:

def shift(str, n): return str[-n:] if n < 0 else '?'*n + str
def read(str, n): assert not '?' in str; return str[n]
def write(str, n, ch): return str[:n] + ch + str[n:]

S = 'ab'
x = read(S, 1)
S = shift(S, 1)
S = write(S, 0, x)

这一系列步骤将对应于解决方案 [('R', 1, 'x'), ('S', 1), ('W', 0, 'x')]

我觉得这个问题和 av 之间有一些相似之处 levenshtein 编辑距离,但我无法弄清楚。 你也可以 为我编写翻译算法?

如果这个问题描述不够清楚,我会添加更多示例 但我希望如此。

最佳答案

首先,我想我修复了您的 Python 代码。这是一个可以运行一系列步骤并给出结果的类。您的示例在结果中留下了 ?,我认为这是不应该发生的。

这是SequenceRunner

class SequenceRunner:

    def __init__(self):
        self.INSTRUCTIONS = {
            'R': self.read,
            'S': self.shift,
            'W': self.write
            }

    def set(self, S):
        self.S = S[::-1]

    def shift(self, n):
        self.S = self.S[-n:] if n < 0 else  '?'*n + self.S

    def read(self, n, v):
        assert not '?' in self.S; return self.S[n]

    def write(self, n, v):
        v = getattr(self, v)
        self.S = self.S[:n] + v + self.S[n+1:]

    def run(self, program):
        for line in program:
            func = self.INSTRUCTIONS[line[0]]
            args = line[1:]
            result = func(*args)
            if result:
                setattr(self, args[-1], result)

    def get(self):
        return self.S[::-1]

下面是使用方法

c = SequenceRunner()
program = [('R', 1, 'x'), ('S', 1), ('W', 0, 'x')]
c.set('ab')
c.run(program)
print c.get()

问题以便我更好地理解:您是否需要一种算法来推断从一个字符串到另一个字符串所需的(最少的)步骤?

关于python - 使用尽可能少的步骤转换序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27636207/

相关文章:

javascript - Damerau-Levenshtein 距离实现

python - 链接测试并将对象从一个测试传递到另一个测试

arrays - 两个数组中元素序列的相似程度如何

php - Django 、Python : Is there a simple way to convert PHP-style bracketed POST keys to multidimensional dict?

algorithm - 讲座幻灯片说明 : Computable in Polynomial Time

javascript - 如何制作识别相似元素字符串的 JavaScript 代码?

string - 对一长串单词进行聚类

python - 如何将 python/cython unicode 字符串转换为长整数数组,以进行 levenshtein 编辑距离

python - 我想帮助优化带有 if in 语句的三重 for 循环

python - 如何比较numpy多维数组的差异?