
本文介绍一种高效、简洁的方法,使用取模与整除运算统计 1 至 100 所有整数中各数字 0–9 的出现频次,避免字符串转换与异常处理,代码更健壮、可读性更强。
在编写数字频次统计程序时,常见的误区是依赖字符串操作(如 String.valueOf() 和 charAt()),不仅效率低,还容易因索引越界引发异常(如对个位数调用 charAt(1)),导致逻辑错误或运行时崩溃。更优解是采用纯数学方法:对每个整数反复执行 val % 10 获取个位数字,再通过 val /= 10 去掉该位,直至数值归零。
以下为推荐实现:
public class CountEachDigit {
public static void main(String... args) {
final int lo = 1;
final int hi = 100;
int[] digits = countDigits(lo, hi);
for (int i = 0; i < 10; i++) {
System.out.format("The digit %d appears %d times between %d and %d.\n",
i, digits[i], lo, hi);
}
}
private static int[] countDigits(int lo, int hi) {
int[] digits = new int[10]; // 索引 0~9 分别对应数字 0~9 的计数
for (int i = lo; i <= hi; i++) {
int val = i;
do {
digits[val % 10]++; // 提取当前最低位数字并计数
} while ((val /= 10) > 0); // 去掉已处理的最低位,继续循环
}
return digits;
}
}✅ 关键优势说明:
- 无字符串开销:避免创建大量临时 String 对象,提升性能;
- 无异常风险:do-while 循环天然适配任意位数(1 位、2 位、3 位数均安全);
- 逻辑清晰:val % 10 恒得当前个位,val /= 10 是整数截断除法,语义明确;
- 可扩展性强:只需修改 lo 和 hi 即可适配任意正整数区间(如 1–1000)。
? 注意事项:
- 此方法默认统计 所有数字字符 的出现次数(例如 100 包含两个 '0' 和一个 '1',共贡献 3 次);
- 若需排除前导零(如不将 5 视为 "005"),本逻辑已天然满足——因只处理实际数值位,无需额外判断;
- 数组 digits 初始化为全 0,确保计数从零开始,无需手动清零。
运行结果示例:
The digit 0 appears 11 times between 1 and 100. The digit 1 appears 21 times between 1 and 100. The digit 2 appears 20 times between 1 and 100. ... The digit 9 appears 20 times between 1 and 100.
掌握这种基于模运算的数字拆解技巧,不仅能解决本题,更是处理进制转换、回文判断、数字反转等编程问题的核心基础。










