Java竞赛计时程序数组默认值0干扰计算结果问题求助
问题根源分析
你碰到的问题核心非常明确:你固定创建了长度为6的数组,但只给前contestants个位置(索引1到contestants)赋值,剩下的数组元素默认是0,而后续计算最快、最慢、总和以及统计人数时,循环遍历了整个数组的所有元素(包括那些未赋值的0)。
比如当参赛人数是4时,数组索引1-4被赋值,索引5还是0,你的循环会从1跑到5(因为milisecs.length是6,i<6),所以0会被当成有效时间参与计算,自然会把最快时间拉到0,统计快于平均的人数时也多算一个。而参赛人数是5时,刚好索引1-5都被赋值,循环范围刚好覆盖所有有效数据,所以没问题。
解决方案
最直接的修复方式是让数组长度和实际参赛人数匹配,同时尽量遵循Java数组从0开始索引的规范(当然你也可以继续用1索引,但0索引更符合Java的常规写法)。下面是修改后的完整代码,我会标注关键修改点:
import java.util.Scanner; public class FastestFingers { public static void main(String[] args) { //declare variables int contestants; // 修改点1:不再固定数组长度,先声明后初始化 int [] milisecs; int fastest, slowest, i; int faster = 0; double average; Scanner scanInt = new Scanner (System.in); //make user enter number of contestants System.out.println ("Enter # of contestants: "); contestants = scanInt.nextInt(); // 修改点2:获取参赛人数后,初始化对应长度的数组 milisecs = new int[contestants]; //make user enter times // 修改点3:循环从0开始,遍历到contestants-1,覆盖所有参赛选手 for(i=0;i<contestants;i++) { System.out.println ("Time (ms) for contestant " + (i+1) + ": "); milisecs[i] = scanInt.nextInt(); } //calculate fastest time // 修改点4:初始值设为第一个选手的时间(索引0) fastest = milisecs[0]; // 修改点5:只遍历实际输入的选手时间 for(i=0;i<contestants;i++) { if(milisecs[i] < fastest) { fastest = milisecs[i]; } } System.out.println ("Fastest: " + fastest); //calculate slowest time slowest = milisecs[0]; for(i=0;i<contestants;i++) { if(milisecs[i] > slowest) { slowest = milisecs[i]; } } System.out.println ("Slowest: " + slowest); //tell program how to find average int total = 0; for(i=0;i<contestants;i++) { total = total + milisecs[i]; } // 修改点6:转成double避免整数除法精度丢失 average = (double)total / contestants; //find numbers faster than the average int count = 0; for(i=0;i<contestants;i++) { if(milisecs[i]<average) { count++; } } System.out.println ("Faster than average: " + count); // 关闭Scanner避免资源泄漏 scanInt.close(); } }
额外优化说明
- 改用0索引是Java的标准用法,能避免浪费数组空间(原来的索引0一直没用到)。
- 新增了选手编号提示,用户输入时更清楚是给哪个选手录时间。
- 修复了整数除法的问题:原来的
total/contestants会丢失小数部分,转成(double)total / contestants后能得到精确的浮点数平均。 - 最后关闭了Scanner,避免不必要的资源泄漏。
如果你坚持想继续用1索引的写法,也可以把数组长度设为contestants+1,然后所有循环都从1跑到contestants,这样也能避开未赋值的0元素,但还是推荐0索引的写法哦。
内容的提问来源于stack exchange,提问作者Speacial Nimbleseamus




