初级算法_字符串_报数

题目描述

报数序列是一个整数序列,按照其中的整数的顺序进行报数,得到下一个数。其前五项如下:

1 1
2 11
3 21
4 1211
5 111221

1 被读作 “one 1” (“一个一”) , 即 11。 11 被读作 “two 1s” (“两个一”), 即 21。 21 被读作
“one 2”, “one 1” (“一个二” , “一个一”) , 即 1211。

给定一个正整数 n(1 ≤ n ≤ 30),输出报数序列的第 n 项。

注意:整数顺序将表示为一个字符串。

示例 1:

输入: 1 输出: “1”

示例 2:

输入: 4 输出: “1211”

解题思路

这道题激起了我强大的好奇心,好想知道用时最短的那个是不是把答案都算出来然后switch case。想想还有点小激动。

这种类型的题我一般先看看有没有什么通解,有的话列个算式就出来了,然而没找着。
第二种思路就是递归,或者迭代。

这道题我用的递归的方法,步骤如下:

  1. n = 1时,返回“1”;
  2. n != 1时,调用此函数本身获取 n-1的结果;
  3. 获取到n-1的读数后,计算得到n的读数,返回。

代码

char * countAndSay(int n) {
    char *pcRet = 0;
    int i = 0;
    int iStrLen = 0;
    int iLastStrLen = 0;
    int iRetLen = 0;
    int iCount = 1;
    int iIndex = 0;
    char *pcLastRet = 0;

    if (1 == n)
    {
        pcRet = (char *) malloc(2 * sizeof(char));
        pcRet[1] = 0;
        *pcRet = '1';
        return pcRet;
    }

    pcLastRet = countAndSay(n - 1);

    /* 第一次遍历获取需要内存的大小 */
    iLastStrLen = strlen(pcLastRet);
    for ( i = 0; i < iLastStrLen; i++)
    {
        if (pcLastRet[i] != pcLastRet[i+1])
        {
            iRetLen++;
        }
    }

    pcRet = (char *) malloc((iRetLen * 2 + 1) * sizeof(char));
    pcRet[iRetLen * 2] = 0;

    /* 填充的字符串 */
    for ( i = 0; i < iLastStrLen; i++)
    {
        if (pcLastRet[i] != pcLastRet[i + 1])
        {
            pcRet[iIndex++] = iCount + '0';
            pcRet[iIndex++] = pcLastRet[i];
            iCount = 1;
        }
        else
        {
            iCount++;
        }
    }

    free(pcLastRet);
    return pcRet;
}

易错点:
说是易错点,其实是我出错的地方。

我果然。。。又又又又一次内存越界了。
其他,感觉就是字符串末尾别忘了加‘0’,边界值要算一下这种吧。

运行结果

在这里插入图片描述

看答案

终于到了令人兴奋的看答案时刻了!
然而很遗憾,并不是我想的那样。。

/* 尾递归 */
char *countHelper(char *s, int n)
{
    if (n == 1)
        return s;
    else
    {
        //求下一个数
        int count;
        char ch[10000];
        char *p = ch;
        //一直读数
        while (*s!='\0')
        {
            count = 1;
            //如果一直是同一个数
            while (*s==*(s+1))
            {
                count++;
                s++;
            }
            //下一个数更新
            *p++ = (char)(count+'0');
            *p++ = *s++;
        }
        return countHelper(ch, n - 1);
    }
}

char *countAndSay(int n)
{
    return countHelper("1", n);
}

这个n竟然是计算的次数。。感觉这代码写的比起递归更像是迭代,直接写个循环多好。
而且,这是返回了一个动态变量吗??还是我理解错了??

总结

哪天数组没访问越界我一定要吃好吃的庆祝下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值