问题描述
有一种简单的字符串压缩算法,对于字符串中连续出现的同一个英文字符,用该字符加上连续出现的次数来表示(连续出现次数小于3时不压缩)。
例如,字符串aaaaabbbabaaaaaaaaaaaaabbbb可压缩为a5b3aba13b4。
请设计一个程序,将采用该压缩方法得到的字符串解压缩,还原出原字符串并输出。
输入说明
输入数据为一个字符串(长度不大于50,只包含字母和数字),表示压缩后的字符串
输出说明
在一行上输出解压缩后的英文字符串(长度不超过100),最后换行。
输入样例
aaaaabbbabaaaaaaaaaaaaabbbb
输出样例
a5b3aba13b4
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
char * compress(char * src) {//字符串压缩函数
int len = strlen(src);
char * compressed = (char *)malloc(len * sizeof(char));//为压缩后的新字符串分配内存
//压缩后的字符串长度不超过原字符串长度
int index = 0;//新字符串索引
int count = 1;//计数
for (int i = 0; i < len - 1; i++){//遍历到倒数第二个字符串即可
char current = src[i];//current暂时存储字符src[i]
if (src[i] == src[i + 1]) {
count++;
} else {
compressed[index++] = current;
if (count == 2) {
compressed[index++] = current;//count为2时不必压缩
} else if (count > 2) {
sprintf(compressed + index, "%d", count);
//调用sprintf函数,将格式化的数据写入字符串中
index += (int)floor(log10(count)) + 1;
//调用floor和log函数,递增索引的值
//在C语言中,floor函数用于返回小于或等于其参数的最大整数值。它需要包含math.h头文件。
//log10(x)的返回值类型为浮点型,需要使用强制类型转换,在前面加(int),由x是一位数、二位数、三位数
//分别返回范围在(0,1),[1,2),[2,3)的浮点数
//因此count为一位数时,index递增1,count为两位数时,index递增2,以此类推
count = 1;//重置count的值
}
}
}
compressed[index] = '\0';//末尾添加空字符
return compressed;//返回指向压缩后字符串的指针
}
int main() {
char original[100];
fgets(original, 100, stdin);
char * result = compress(original);
printf("%s\n", result);
free(result);//释放内存
return 0;
}
这里需要介绍sprintf函数用法,以便于你理解程序:
sprintf函数用于将格式化的数据写入字符串中。它的函数原型如下所示:
int sprintf(char *str, const char *format, ...);
其中,str
是要写入的字符串,format
是格式化字符串,后面的参数是根据format
中指定的格式进行填充的数据。
以下是一个简单的C程序示例,演示了sprintf函数的用法:
#include <stdio.h>
int main() {
char buffer[100];
int num = 123;
float fnum = 3.14;
// 将格式化数据写入buffer中
sprintf(buffer, "The number is %d and the float number is %.2f", num, fnum);
// 打印buffer中的内容
printf("Buffer: %s\n", buffer);
return 0;
}
在这个示例中,sprintf函数将整数num
和浮点数fnum
按照指定的格式写入到buffer
字符串中,然后通过printf函数打印出来。
需要注意的是,在使用sprintf函数时要确保目标字符串有足够的空间来存放格式化后的数据,以防止溢出。