学习别人的优秀写法,能想到用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; }