在线编译器 C

#include <stdio.h> #include <string.h> void result(char c[]) { int i = 0; int counter = 1; while (c[i] != '\0') { if (c[i] == c[i + 1]) { counter++; } if (c[i] != c[i + 1] || c[i + 1] == '\0') { printf("%c%d", c[i], counter); counter = 1; } i++; } } int main() { char a[1001]; scanf("%[^\n]", a); result(a); return 0; }
这段代码实现了一个简单的“游程编码”功能,将字符串中连续相同的字符压缩成“字符+重复次数”的形式输出。例如输入 `aaabbbcc` 会输出 `a3b3c2`。

代码逻辑基本正确,但有一个边界情况可能导致输出错误。

- 当字符串末尾的字符连续出现时,第二个 `if` 条件中的 `c[i + 1] == '\0'` 检查是为了在最后一个字符时触发输出。但注意,这个条件与 `c[i] != c[i + 1]` 是“或”的关系,当 `c[i + 1]` 是结束符时,`c[i] != c[i + 1]` 一定为真(因为结束符不等于任何可见字符),所以实际上 `c[i + 1] == '\0'` 这个判断是多余的,不会造成问题。

- 主要问题在于:当 `c[i]` 是字符串的最后一个字符(即 `c[i+1]` 是 `'\0'`)时,循环体执行完后 `i` 会自增,然后 `while` 条件检查 `c[i] != '\0'`,此时 `c[i]` 已经是结束符,循环正常结束。但如果在最后一个字符之前,连续字符的计数已经完成,输出是正确的。然而,考虑一种特殊情况:如果字符串只有一个字符,比如 `"a"`,第一次循环时 `c[0]` 是 `'a'`,`c[1]` 是 `'\0'`,第一个 `if` 不成立,第二个 `if` 成立,输出 `a1`,然后 `i` 变为1,循环结束,结果正确。所以代码似乎能处理单字符情况。

- 但仔细检查:当连续字符出现在字符串中间时,比如 `"ab"`,第一次循环 `c[0]='a'`,`c[1]='b'`,第一个 `if` 不成立,第二个 `if` 成立(因为 `c[0]!=c[1]`),输出 `a1`,`counter` 重置为1。第二次循环 `c[1]='b'`,`c[2]='\0'`,第一个 `if` 不成立,第二个 `if`