【发布时间】:2014-06-19 01:12:30
【问题描述】:
挑战说明在这里:https://www.codeeval.com/browse/130/
两条规则:
- “0”可以转化为字母“A”的非空序列(“A”、“AA”、“AAA”等)
- “1”可以转换为字母“A”的非空序列(“A”、“AA”、“AAA”等)或字母“B”的非空序列(“B”、“BB” "、"BBB" 等)例如
测试用例:
- 1010 AAAAABBBBAAAA ==> 是
- 00 AAAAAA ==> 是的
- 01001110 AAAABAAABBBBBBAAAAAAA ==> 是
- 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;
}
我的问题是:
- 如何证明上面代码的正确性(讽刺的是,我对我写的递归不是很有信心)?
- 如果代码不对,该如何调试?
- 假设我的代码是正确的,很明显递归不是最好的解决方案(回溯太多),我有一种用DP来解决的感觉。我尝试过记忆化来存储(i,j)的结果,但仍然失败。需要解决这个问题的想法。
感谢您的时间和 cmets!
【问题讨论】:
-
在读取第二个字符串的每个连续字符时跟踪您可能处于的状态。定义一个递归关系,从字符 i - 1 计算字符 i 的状态。
-
@jonderry,感谢您的提示,问题已解决!
标签: algorithm recursion dynamic-programming