【问题标题】:CodeEval / Sequence Transformation Code TimeoutCodeEval / 序列转换代码超时
【发布时间】:2014-06-19 01:12:30
【问题描述】:

挑战说明在这里:https://www.codeeval.com/browse/130/

两条规则:

  1. “0”可以转化为字母“A”的非空序列(“A”、“AA”、“AAA”等)
  2. “1”可以转换为字母“A”的非空序列(“A”、“AA”、“AAA”等)或字母“B”的非空序列(“B”、“BB” "、"BBB" 等)例如

测试用例:

  1. 1010 AAAAABBBBAAAA ==> 是
  2. 00 AAAAAA ==> 是的
  3. 01001110 AAAABAAABBBBBBAAAAAAA ==> 是
  4. 1100110 BBAABABBA ==> 没有

我想到的解决方案是正则表达式,我递归地实现了。对于上面的小测试用例,它工作正常。但是对于长字符串,代码运行超时超过10秒。

比如下面这种情况需要“forever”才能得到结果:

00111010000001000111010000101111110101110001001 AAAAAAAAAAAAAAABBBBBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBAAAAAAAAAAAAAAAAAAAAAABBBBAAAAAAAAAABBBBBBBBBBBBBAAAAAAAAAAABBBBBBAAAABBAAAAAAAAAAAAAAA

还有更长的案例等待测试。

这是我的代码:

#include <iostream>
using namespace std;

bool validate(string pattern, int i, string text, int j);

bool matchA(string pattern, int i, string text, int j)
{
    while(j < text.size() && text[j] == 'A')
    {
        j++;
        if(validate(pattern, i+1, text, j))
            return true;
    }
    return false;
}

bool matchAB(string pattern, int i, string text, int j, char c)
{
    while(j < text.size() && text[j] == c)
    {
        j++;
        if(validate(pattern, i+1, text, j))
            return true;
    }
    return false;
}

bool validate(string pattern, int i, string text, int j)
{
    if(i == pattern.size())
        return j == text.size();
    if(pattern[i] == '0')
        return matchA(pattern, i, text, j);
    if(pattern[i] == '1')
        return matchAB(pattern, i, text, j, text[j]);
    return false;
}

int main(int argc, char* argv[])
{
    string pattern = "00";
    string text = "AAAAA";
    if(validate(pattern, 0, text, 0))
        cout << "Yes" << endl;
    else
        cout << "No" << endl;
    return 0;
}

我的问题是:

  1. 如何证明上面代码的正确性(讽刺的是,我对我写的递归不是很有信心)?
  2. 如果代码不对,该如何调试?
  3. 假设我的代码是正确的,很明显递归不是最好的解决方案(回溯太多),我有一种用DP来解决的感觉。我尝试过记忆化来存储(i,j)的结果,但仍然失败。需要解决这个问题的想法。

感谢您的时间和 cmets!

【问题讨论】:

  • 在读取第二个字符串的每个连续字符时跟踪您可能处于的状态。定义一个递归关系,从字符 i - 1 计算字符 i 的状态。
  • @jonderry,感谢您的提示,问题已解决!

标签: algorithm recursion dynamic-programming


【解决方案1】:

感谢@jonderry 的提示,这里是 DP 解决方案:

假设State[i,j]用来保存pattern[i]和text[j]的状态,如果State[i,j] == true,我们说从pattern[0]到pattern[i ] 并且从 text[0] 到 text[j],序列转换是有效的。 因此,我们可以根据以下条件计算 State[i,j]:

State[i,j] =
1. (pattern[i] == '0' and text[j] == 'A') or pattern[i] == '1'   // if State[i-1,j-1] = true
2. State[i-1,j] && text[j-1] == text[j],                         // otherwise 

感谢您的宝贵时间和 cmets!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-17
    • 1970-01-01
    • 2013-03-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多