C#实现字母计数功能时出现非预期重复输出问题
问题现象
程序核心功能为接收输入字符串,统计每个字母的出现次数,统计时自动忽略输入中的数字。首次运行时统计结果符合预期,第二次输入内容时会出现统计结果重复的异常:
- 预期:输入
aAaAaA时仅输出A6 - 实际异常:首次输入
aAaAaA输出A6,第二次输入相同内容时输出A6 A2
实际运行输出:
aAaAaA A6 aAaAaA A6 A2
原实现代码
string input = Console.ReadLine().ToUpper(); while (input[0] != 'q') { int[] counting = new int[26]; Array.Clear(counting, 0, counting.Length); //string to array conversion if (input.Length > 0 && input.ToUpper()[0] == 'Q') return; string all = "."; for (int i = 0; i < input.Length; i++) { bool checking = false; string number = ""; for (int j = 0; j < input.Length; j++) { if (input.ToUpper()[i] == input.ToUpper()[j]) { number += input.ToUpper()[i]; } } for (int j = 0; j < all.Length; j++) { if (input[i] == all[j]) { checking = true; } } all += input[i]; if (!checking) { input = Regex.Replace(input, @ "[\d-]", string.Empty); Console.Write(number[0].ToString() + number.Length.ToString() + " "); } } Console.WriteLine(); input = Console.ReadLine();
故障原因
代码存在三个直接导致异常的问题:
- 输入处理逻辑不一致:首次读取输入时调用了
.ToUpper()统一转大写,但循环末尾读取下一轮输入的代码input = Console.ReadLine()没有做大写转换,第二轮输入的大小写字符判断逻辑失效。 - 正则过滤位置和写法错误:移除数字的正则替换逻辑写在遍历统计的循环内部,第一次输出结果后才会修改input字符串,遍历过程中字符串长度变化会导致索引错位,后续字符统计重复;同时
@和字符串开头之间多了空格,会导致正则匹配失效。 - 去重逻辑顺序错误:用于标记已统计字符的
all字符串,在去重校验之前就拼接了当前遍历的字符,会导致已统计字符被重复判定为未统计,触发重复输出。
另外代码一开始声明的counting数组完全没有被使用,反而用双层嵌套循环做字符计数,逻辑冗余且容易出错。
修复方案
- 统一所有输入的大写转换逻辑,每轮读取输入后都调用
.ToUpper()做标准化处理,同时增加空值判断避免索引越界 - 将数字过滤逻辑移到遍历统计之前执行,遍历过程中不修改原输入字符串,避免索引错位,同时修正正则写法错误
- 直接使用预先声明的
counting数组做字符计数,去掉冗余的双层循环和有漏洞的all字符串去重逻辑
修复后的可运行代码:
using System; using System.Text.RegularExpressions; class LetterCounter { static void Main() { string input = Console.ReadLine().ToUpper(); while (!string.IsNullOrEmpty(input) && input[0] != 'Q') { int[] counting = new int[26]; // 遍历前先过滤数字和横杠 input = Regex.Replace(input, @"[\d-]", string.Empty); // 遍历字符统计次数 foreach (char c in input) { if (char.IsLetter(c)) { counting[c - 'A']++; } } // 输出统计结果 for (int i = 0; i < 26; i++) { if (counting[i] > 0) { Console.Write($"{(char)('A' + i)}{counting[i]} "); } } Console.WriteLine(); // 读取下一轮输入时统一转大写 input = Console.ReadLine().ToUpper(); } } }
内容的提问来源于stack exchange,提问作者Altuism
相关产品推荐
相关产品推荐

