C 语言实现字符串压缩:从思路到代码详解

字符串压缩是编程中常见的基础问题,核心目标是通过简化重复字符的表示来减少字符串长度。本文将带大家从零开始,用 C 语言实现一个简单的字符串压缩功能,并深入解析其中的逻辑细节。

一、需求分析:我们要做什么?

首先明确压缩规则:

  • 对于连续重复的字符,用「字符 + 重复次数」表示(例如 "aaab" 压缩为 "a3b"
  • 若重复次数为 1,则不记录次数(例如 "abc" 压缩后仍为 "abc"
  • 若压缩后的字符串长度没有缩短,则输出 "NO"(例如 "aabb" 压缩后为 "a2b2",长度不变,输出 "NO")

二、核心思路:如何实现压缩?

要实现字符串压缩,关键在于统计连续重复字符的次数,步骤可拆解为:

  1. 遍历原始字符串,定位连续重复字符的起始位置(用i标记)
  2. 从起始位置向后查找,直到找到第一个不同的字符(用j标记结束位置)
  3. 计算重复次数:j - i(结束位置 - 起始位置)
  4. 根据重复次数决定如何存入压缩后的字符串:
    • 若次数 > 1:存入「字符 + 次数」
    • 若次数 = 1:只存入字符
  5. 最后比较压缩前后的长度,决定输出结果

三、代码实现:一步步构建功能

1. 准备工作:定义变量与输入

首先需要定义存储原始字符串和压缩后字符串的数组,以及辅助变量:

#include <stdio.h>
#include <string.h>  // 用于strlen函数

int main() {
    char str[502];    // 存储输入字符串(预留结束符位置)
    char target[502]; // 存储压缩后的字符串
    int k = 0;        // target数组的当前下标(记录已存入字符数)
    
    // 读取输入字符串
    scanf("%s", str);
    int len = strlen(str);  // 计算原始字符串长度

2. 核心逻辑:遍历与压缩

使用循环遍历原始字符串,通过双指针ij统计连续重复字符:

    // 遍历原始字符串,i是当前字符的起始下标
    for (int i = 0; i < len;) {
        int j = i;  // j用于查找连续重复的结束位置
        
        // 找到第一个与str[i]不同的字符位置
        while (str[i] == str[j]) {
            j++;  // 只要字符相同,j就后移
        }
        
        // 根据重复次数处理压缩
        if (j - i > 1) {  // 重复次数>1,需要记录次数
            target[k++] = str[i];          // 先存字符
            target[k++] = (j - i) + '0';   // 再存次数(转为字符)
        } else {  // 重复次数=1,只存字符
            target[k++] = str[i];
        }
        
        i = j;  // 跳过已处理的字符,i直接指向j(下一组字符的起始)
    }

3. 结果处理:判断是否有效压缩

压缩完成后,需要给target添加字符串结束符,并比较长度:

    target[k] = '\0';  // 添加结束符,确保字符串合法
    
    // 比较压缩前后的长度
    if (k == len) {
        printf("NO");  // 长度不变,输出NO
    } else {
        printf("%s", target);  // 输出压缩后的字符串
    }
    
    return 0;
}

四、关键细节解析

  1. 双指针ij的作用

    • i 始终指向当前要处理的连续字符的起始位置
    • j 从i出发,向后移动直到找到不同的字符,因此j - i就是重复次数
  2. 字符与数字的转换

    • 代码中用 (j - i) + '0' 将数字转为字符(例如 3 + '0' = '3')
    • 注意:这种方式仅支持次数≤9 的情况(若次数≥10,需要特殊处理多位数)
  3. 数组下标k的更新

    • 每次存入字符后,k通过k++自动加 1,确保下一次存储不会覆盖当前内容
    • 最终k的值就是压缩后字符串的长度(不含结束符)

五、扩展思考

本文实现的压缩功能较为基础,实际应用中可考虑扩展:

  • 支持重复次数≥10 的情况(例如aaaaaaaaaaaa11
  • 处理带空格或特殊字符的字符串
  • 实现压缩算法的逆过程(解压缩)

通过这个案例,我们不仅掌握了字符串压缩的基本逻辑,更熟悉了 C 语言中字符数组、指针遍历等核心操作。希望本文能帮助大家更好地理解字符串处理的思路!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值