给定一串数字,我希望找到将字符串分解为单个数字的方式,以便每个数字都在26以下。
例如," 8888888"只能分解为" 8 8 8 8 8 8 8"。鉴于" 1234567"可以分解为" 1 2 3 4 5 6 7"," 12 3 4 5 6 7"和" 1 23 4 5 6 7"。
我既喜欢解决方案的递归关系,也喜欢使用动态编程的一些代码。
这是我到目前为止所得到的。它只涵盖了一个空字符串的基本情况应该返回1一个数字的字符串应该返回1并且所有大于2的数字的字符串应该返回1.
int countPerms(vector<int> number, int currentPermCount)
{
vector< vector<int> > permsOfNumber;
vector<int> working;
int totalPerms=0, size=number.size();
bool areAllOverTwo=true, forLoop = true;
if (number.size() <=1)
{
//TODO: print out permetations
return 1;
}
for (int i = 0; i < number.size()-1; i++) //minus one here because we dont care what the last digit is if all of them before it are over 2 then there is only one way to decode them
{
if (number.at(i) <= 2)
{
areAllOverTwo = false;
}
}
if (areAllOverTwo) //if all the nubmers are over 2 then there is only one possable combination 3456676546 has only one combination.
{
permsOfNumber.push_back(number);
//TODO: write function to print out the permetions
return 1;
}
do
{
//TODO find all the peremtions here
} while (forLoop);
return totalPerms;
}
答案 0 :(得分:2)
假设您没有零,或者您不允许带前导零的数字),则重复关系为:
N(1aS) = N(S) + N(aS)
N(2aS) = N(S) + N(aS) if a < 6.
N(a) = 1
N(aS) = N(S) otherwise
此处,a
表示单个数字,S
表示数字。递归关系的第一行表示如果你的字符串以1
开头,那么你可以自己拥有它,或者将它与下一个数字连接起来。第二行说明如果你从一个2
开始,你可以自己拥有它,或者将它与下一个数字连接,假设它给出的数字小于26.第三行是终止条件:当你'下降到1位数,结果是1.最后一行说如果你不能匹配以前的规则之一,那么第一个数字不能连接到第二个数字,所以它必须站在它的上面自己的。
可以相当直接地实现递归关系作为迭代动态编程解决方案。这是Python中的代码,但很容易翻译成其他语言。
def N(S):
a1, a2 = 1, 1
for i in xrange(len(S) - 2, -1, -1):
if S[i] == '1' or S[i] == '2' and S[i+1] < '6':
a1, a2 = a1 + a2, a1
else:
a1, a2 = a1, a1
return a1
print N('88888888')
print N('12345678')
输出:
1
3
一个有趣的观察结果是N('1' * n)
是第n + 1'个斐波纳契数:
for i in xrange(1, 20):
print i, N('1' * i)
输出:
1 1
2 2
3 3
4 5
5 8
6 13
7 21
8 34
9 55
答案 1 :(得分:1)
如果我理解正确,只有25种可能性。我的第一个解决方案是将一个25个整数的数组初始化为零,当我找到一个小于25的数字时,将该索引设置为1.然后,当我看完该数据后,我会计算数组中的所有1字符串。
复发意味着什么?如果您正在寻找递归函数,则需要找到一种以递归方式打破数字串的好方法。我不确定这是最好的方法。我会直接逐个数字,如你所说,如果数字是2或更少,然后存储它并测试附加下一个数字...即10 *数字+下一个。我希望有所帮助!祝你好运。
答案 2 :(得分:1)
考虑它的另一种方法是,在最初的单个数字可能性之后,对于长度为n
的每个连续可能的数字对(例如,111或12223)的每个序列,我们将结果乘以:
1 + sum, i=1 to floor (n/2), of (n-i) choose i
例如,序列号为11111,我们可以
i=1, 1 1 1 11 => 5 - 1 = 4 choose 1 (possibilities with one pair)
i=2, 1 11 11 => 5 - 2 = 3 choose 2 (possibilities with two pairs)
这似乎与维基百科对斐波那契数字的描述直接相关。 &#34;在数学中使用,&#34;例如,计算&#34; 1和2的组合数量总和为给定的总数n&#34; (http://en.wikipedia.org/wiki/Fibonacci_number)。
使用组合方法(或其他快速斐波那契方法)可能适用于序列很长的字符串。