代码改变世界

字符串的组合个数

2014-12-12 19:35  李涛的技术博客  阅读(779)  评论(0编辑  收藏  举报

有一个MAP,KEY从a到z,对应的VALUE从1到26,比如:

a = 1

b = 2

...

z = 26,对于一个数字字符串"11",可以由"aa"对应的数字组合,也可以由"k"对应的数字代表,对应组合的个数记为2;同样,比如"111"对应的组合个数是3,分别是"aaa", "ka", "ak"。

给定一个数字数组,计算对应的组合个数。

 

解答:对于一个字符串,定义f(x)为前x个字符的组合个数,那么:

f(x) = f(x-2)               if 最后一个数字是'0'

      = f(x-1)               else if (倒数第二个数字是'0' || 最后两个数大于"26")

      = f(x-1)+f(x-2)     else

int last2num(char* arr, int len)
{
    assert(arr != NULL && len >= 2);
    int num = (arr[len-2]-'0')*10 + (arr[len-1]-'0');
    if (num <= 26)
        return 2;
    else
        return 1;
}

int countKind(char* arr, int len)
{
    if (arr == NULL || len <= 0)
        return 0;
    if (len == 1)
        return 1;
    if (len == 2)
    {
        if (arr[len-1] == '0' || last2num(arr, len) > 26)
            return 1;
        else 
            return 2;
    }
    if (arr[len-1] == '0')
        return countKind(arr, len-2);
    else if (arr[len-2] == '0' || last2num(arr, len) > 26)
        return countKind(arr, len-1);
    else
        return countKind(arr, len-1) + countKind(arr, len-2);
}

另一种写法:

上面用的递归,countKind有重复计算,一种方法是把计算过的保存在一个数组里,计算是查一下,如果算过,直接返回结果;另一种方法是从0开始顺序计算,代码如下:

int last2num(char* arr, int len)
{
    assert(arr != NULL && len >= 2);
    return 10*(arr[len-2]-'0') + (arr[len-1]-'0');
}

int countKind(char* arr, int len)
{
    if (arr == NULL || len <= 0)
        return 0;
    if (len == 1)
        return 1;
    else if (len == 2)
    {
        if (arr[len-1] == '0' || last2num(arr, len) > 26)
            return 1;
        else
            return 2;
    }
    int cnt[len+1];
    cnt[0] = 0;
    cnt[1] = 1;
    if (arr[1] == '0'  || last2num(arr, 2) > 26)
        cnt[2] = 1;
    else
        cnt[2] = 2;
    for (int i = 3; i <= len; i++)
    {
        if (arr[i-1] == '0')
            arr[i] = arr[i-2];
        else if (arr[i-2] == '0' || last2num(arr, 2) > 26)
            arr[i] = arr[i-1];
        else
            arr[i] = arr[i-1] + arr[i-2];
    }
    return arr[len];
}

长度等于2的单独计算是必要的,为了解决类似"70"这样的case。