学习别人的优秀写法,能想到用log10(x)的真是人才!
用双指针,刚开始均指向第一个字母,然后开始比较,(每轮比较第一次比较的其实是同一个字母,第二次才是正式比较才决定要不要压缩)
如果后面指针所指元素和前面不同,说明前面字母只出现一次,那么在字符串中保留该字母,用新指针进行赋值。
如果后面指针所指元素和前面相同,说明需要压缩了,但先得找出该字母出现了几次,指针继续后移直到所指不一样,下标差值即使出现次数。
次数算出来之后,又有问题,因为不是直接赋值,次数是整型,字母是字符型,要赋值,只能赋2-9,两位数需要2个字符,三位数需要3个字符。
比起单独讨论二位数次数,三位数次数,四位数次数的情况,终于看到一个优秀人才用到了log10(x)来确定所需字符的个数
从后往前依次填入个位数,十位数,百位数等,当然,是字符型,不是整型
遍历完所有字母后,加上结束标志'\0'.
char* compressString(char* param ) {
   if(param == NULL)
       return NULL;   //字符串为空的特殊情况单独处理
    int i=0, j=0, k=0;
    int len = strlen(param);
    while(i<len){
        for(j = i; j<len; j++) //一个前指针,一个后指针,刚开始指向同一个元素,每次while开始都是指同一个字母
            if(param[j] != param[i])  //如果后指针与前指针指的不是同一个字母
                break;   //跳出for循环开始压缩该字母
        int cnt = j - i;   //j-i就是该字符连续出现的次数
        param[k++] = param[i];  //先把字符保留,指针后移一位,开始讨论填入几的问题
        if(cnt >1 && cnt < 10)  //如果该字符连续出现次数为个位数
            param[k++] = cnt + '0';  //那么只需要一位便可解决,
                       //因为是字符型,不是整型,所以次数要转化为字符型,加上字符0即可
        else if(cnt >= 10){  //如果次数大于等于10,那就复杂了,可能是两位数,三位数,四位数等
                            //那么就需要用到2个,3个,4个字符来存储
            int tmp = k + (int)log10(cnt);   //用log可以算出是几位数,tmp是填入数字的最后一个下标
            k = tmp + 1;  // k 作为下一个字母的下标
            while(cnt > 0){ 
                param[tmp--] = cnt % 10 +'0';  //从个位数开始填,从低到高,从右往左
                cnt = cnt / 10;  //填完尾数就截断尾数,继续填下一位高位
            }
        }
        i = j;   //j是下个字母的下标,填完一个字母的次数后继续下一轮检查和压缩     
    }
    param[k] = '\0';  //务必自己添加字符串结束标志
    return param;
}