测试用例出错,求排查无数组实现列W奇偶统计的C语言代码问题
我最近在做一个编程作业,任务要求是这样的:
输入m和n,程序读取m行,每行包含n个仅为'W'和'B'的字符。输出规则:若每列中'W'的数量为偶数,则输出'B',否则输出'F'。注意:不允许使用数组!
举个例子,输入:
3 2 WB WB BB
对应的输出应该是BB(第一列有2个W,偶数输出'B';第二列有0个W,偶数输出'B')。
我自己写了一段代码,但测试时总是得到错误结果,代码如下:
scanf("%d %d",&n,&m); for(int i=1;i<=m;i++) { str = 0; for(int j=1;j<=n+1;j++) { scanf("%c",&c); if(c=='W') str = str*1000+1; else str = str*1000; }//end of getting characters sumstr += str; }//end of getting lines //Reversing the "sumstr" while(sumstr>0) { a = sumstr%1000; reverse = (reverse+a)*1000; sumstr/=1000; } reverse/=1000; for(int k =1;k<=n;k++) { a=reverse%1000; if(a%2==0) printf("B"); else printf("F"); reverse /= 1000; }//End of printing 'B' and 'F'
现在想请大家帮忙排查一下代码里的问题,看看哪里出错了?
问题分析与修正方案
我仔细检查了你的代码,发现几个关键问题:
1. 输入顺序完全搞反了
作业要求输入的是m(行数)和n(列数),但你的代码写成了scanf("%d %d",&n,&m);,把行数和列数的变量弄反了,这直接导致后续循环的次数和读取逻辑全部错误。
2. 字符读取时没有处理换行符
用scanf("%c")读取字符时,会读取输入缓冲区里的所有字符,包括之前输入m和n后留下的换行符。第一次循环的scanf("%c")会读到这个换行符,而不是第一行的第一个字符,导致str的结构完全混乱。另外你循环j从1到n+1,多读了一个字符,也会干扰后续的读取。
3. 数值溢出风险极大
你用sumstr累加每一行的str(每个列用千位分隔的数字存储W的数量),但当m或n稍大时,sumstr会远超int类型的存储范围(比如int最多存储约20亿,而1000^10就是1e30),直接导致数值溢出,结果完全错误。
4. 反转逻辑存在漏洞
你的反转逻辑在处理sumstr时,会导致列的顺序处理错误,而且当某些列的W数量为0时,会丢失这些列的信息。
修正后的代码(推荐用二进制位方案,避免数组且高效)
因为我们只需要知道每列W数量的奇偶性,不需要具体数量,用二进制位存储是最简洁且安全的方式,完全符合“不能用数组”的要求:
#include <stdio.h> int main() { int m, n; scanf("%d %d", &m, &n); getchar(); // 吃掉输入m和n后留下的换行符 // 用二进制位存储每列的奇偶性:第j位为1表示该列W数量为奇数 int col_parity = 0; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { char c = getchar(); if (c == 'W') { // 翻转对应列的奇偶性(异或操作) col_parity ^= (1 << (n - 1 - j)); // 这里用n-1-j是为了让第一列对应二进制的最高位,方便后续输出顺序 } } getchar(); // 吃掉每行末尾的换行符 } // 按列顺序输出结果 for (int j = 0; j < n; j++) { // 取出对应列的奇偶位 int is_odd = (col_parity >> (n - 1 - j)) & 1; printf("%c", is_odd ? 'F' : 'B'); } printf("\n"); return 0; }
代码说明
- 修正了
m和n的输入顺序,确保先读行数再读列数 - 用
getchar()处理输入缓冲区的换行符,避免读取无效字符 - 用二进制位存储每列的奇偶性,完全不会有溢出问题,逻辑简洁
- 读取每个字符时直接更新对应列的奇偶性,不需要后续复杂的数值处理
内容的提问来源于stack exchange,提问作者Ali Hatami

