查找可以派生字符串的不同路径的数量

时间:2014-02-09 23:19:47

标签: string algorithm dynamic-programming

有一条秘密消息是长度至少为2的字符串,仅包含字符A..Z。

对它应用一系列“操作”。操作显示在示例中。

给定最终加密字符串,使用应用于源字符串的一个或多个重复操作计算可能产生此字符串的方式的数量。即使它们对您的秘密消息进行相同的加密,操作也是不同的。 I.E. :从AA获得AAA有四种截然不同的方式。

以下是一个例子:

加密字符串为: ABABA 。输出将是: 8 。以下是您制作ABABA的不同方法:

  1. 从AB开始 - > AB + A - > AB + ABA
  2. 从AB开始 - > AB + A - > ABA + BA 3.从ABA开始 - > AB + ABA
  3. 从ABA开始 - > ABA + BA
  4. 从BA开始 - > A + BA - > AB + ABA
  5. 从BA开始 - > A + BA - > ABA + BA
  6. 从ABAB开始 - > ABAB + A
  7. 从BABA开始 - > A + BABA
  8. 请您帮忙建议一个算法来解决这个问题。我想过尝试递归,但是在更大的输入上,我的代码会慢慢运行。

2 个答案:

答案 0 :(得分:2)

请注意,在派生的每个步骤中,您最终都会使用“加密”字符串的子字符串。存在二次多个(即O(n ^ 2))个子串。

您可以直接找到从每个后缀和前缀派生最终字符串的方法数。

因此,你有二次方可能的子问题,你可以将问题分解为一组完整的子问题,对每个子问题进行计数,并将结果加起来。

通过仅解决每个子问题,您可以获得动态编程算法。这种动态编程算法可以在立方时间内运行。

答案 1 :(得分:0)

不确定这是否正确,但这是JavaScript中的递归尝试:

function f(str){
    var total = 0

    function g(ptr,len){
        for (var i=1; i<= (len%2 == 0 ? len/2 - 1: (len - 1)/2); i++){
            var left = str.substr(ptr,len - i),
                suffix = str.substr(ptr + len - i,i),
                right = str.substr(ptr + i,len - i),
                prefix = str.substr(ptr,i),
                recurseL = false,
                recurseR = false

            if (suffix == left.substr(-i)){
                total++
                recurseL = true
            }
            if (suffix == left.substr(0,i)){
                total++
                recurseL = true
            }
            if (prefix == right.substr(-i)){
                total++
                recurseR = true
            }
            if (prefix == right.substr(0,i)){
                total++
                recurseR = true
            }

            if (recurseR)
                g(ptr + i,len - i)
            if (recurseL)
                g(ptr,len - i)
        }
        return total
    }

    return g(0,str.length)
}

f("ABABA")

输出:

8