Java数组实现顾客消费统计:最值与平均值计算错误排查
问题:用数组+for循环实现顾客消费统计时,最值与平均值计算错误
我正在编写一个Java程序,用来读取商品信息和顾客的购买记录,最终输出消费金额最高、最低的顾客姓名,以及所有顾客的平均消费金额。但目前程序无法准确计算最值和平均值,我怀疑问题出在计算单个顾客总消费金额的环节。另外,我知道用HashMap或者自定义类实现会更简单,但目前还没学过且不被允许使用,只能用for循环和数组来完成。
以下是我的代码:
import java.util.Scanner; public class Store { public static void main(String[] args) { Scanner scan = new Scanner(System.in); // Integer count of number of items in the store int count = scan.nextInt(); // Create an array to store names and prices of each item String[] itemName = new String[count]; double[] itemPrice = new double[count]; for (int i=0; i<count; i++) { // Scan name of each item and price itemName[i] = scan.next(); itemPrice[i] = scan.nextDouble(); } // Integer count for the number of customers int numCustomers = scan.nextInt(); String[] fName = new String[numCustomers]; String[] lName = new String[numCustomers]; double[] costs = new double[numCustomers]; double sum = 0; double average = 0; for (int j=0; j<numCustomers; j++) { fName[j] = scan.next(); lName[j] = scan.next(); //Number of items bought int numItems = scan.nextInt(); for (int k=0; k<numItems; k++) { // For each number of items bought, name and quantity int numItemBought = scan.nextInt(); String nameOfItem = scan.next(); // Find prices of the items customer bought for (int i=0; i<numItems; i++) { // 这里有问题!应该遍历商品总数count,不是当前顾客购买的numItems if (nameOfItem.equals(itemName[i])) { double price = itemPrice[i]; // Calculate the total cost of all items purchased by customer costs[i] = price * numItemBought; // 这里也错了!应该用顾客索引j,并且累加 } } } } // Calculate the sum and average for (int l=0; l<costs.length; l++) { sum = sum + costs[l]; average = sum/costs.length; // 这里没必要每次循环都计算,累加完再算一次就行 } // Find the largest and smallest numbers double temp; for (int p=0; p<costs.length; p++) { for (int j=p+1; j<costs.length; j++) { if(costs[p]>costs[j]) { temp = costs[p]; costs[p] = costs[j]; costs[j] = temp; } } } double smallest = costs[0]; double biggest = costs[costs.length-1]; System.out.println("Biggest: " + biggest + "\nSmallest: " + smallest + "\nAverage: " + average); } }
示例输入
6 Apple 0.25 Banana 0.75 Milk 3.15 Orange 1.25 Salami 2.50 Sponge 1.15 3 Carrie Brownstein 3 2 Banana 1 Orange 2 Milk Corin Tucker 2 3 Banana 2 Sponge Janet Weiss 1 5 Salami
当前输出
Biggest: 6.3 Smallest: 0.0 Average: 2.85
预期输出
Biggest: Janet Weiss (12.50) Smallest: Corin Tucker (4.55) Average: 8.70
问题分析
我帮你找出了几个关键错误:
- 顾客消费金额存储错误:你在计算单个商品的消费时,用了商品数组的索引
i给costs[i]赋值,这完全搞错了——应该用当前顾客的索引j,并且要累加(用+=),而不是直接覆盖,不然每个顾客的消费只会记录最后一个商品的金额。 - 商品遍历范围错误:查找商品价格时,你遍历的是当前顾客购买的商品数量
numItems,但应该遍历商店的所有商品总数count,否则会漏掉不在前numItems位的商品。 - 最值与姓名无法对应:你直接排序了
costs数组,但没有同步排序顾客姓名数组,就算找到最值也没法对应到正确的顾客。 - 平均值计算冗余:每次累加sum都重新计算平均值,完全没必要,等sum累加完成后计算一次即可。
修正后的代码
import java.util.Scanner; public class Store { public static void main(String[] args) { Scanner scan = new Scanner(System.in); // 商店商品总数 int count = scan.nextInt(); String[] itemName = new String[count]; double[] itemPrice = new double[count]; for (int i=0; i<count; i++) { itemName[i] = scan.next(); itemPrice[i] = scan.nextDouble(); } // 顾客数量 int numCustomers = scan.nextInt(); String[] fName = new String[numCustomers]; String[] lName = new String[numCustomers]; double[] costs = new double[numCustomers]; double sum = 0; double average = 0; for (int j=0; j<numCustomers; j++) { fName[j] = scan.next(); lName[j] = scan.next(); int numItems = scan.nextInt(); // 初始化当前顾客的消费为0,避免累加之前的残留值 costs[j] = 0; for (int k=0; k<numItems; k++) { int numItemBought = scan.nextInt(); String nameOfItem = scan.next(); // 遍历所有商品查找对应价格 for (int i=0; i<count; i++) { if (nameOfItem.equals(itemName[i])) { double price = itemPrice[i]; // 累加当前顾客的总消费 costs[j] += price * numItemBought; break; // 找到对应商品后直接跳出循环,提升效率 } } } } // 计算总消费和平均值 for (int l=0; l<costs.length; l++) { sum += costs[l]; } average = sum / costs.length; // 找最值对应的顾客索引,不排序数组,避免打乱姓名对应关系 int maxIndex = 0; int minIndex = 0; for (int m=1; m<numCustomers; m++) { if (costs[m] > costs[maxIndex]) { maxIndex = m; } if (costs[m] < costs[minIndex]) { minIndex = m; } } // 按照预期格式输出,保留两位小数 System.out.printf("Biggest: %s %s (%.2f)\n", fName[maxIndex], lName[maxIndex], costs[maxIndex]); System.out.printf("Smallest: %s %s (%.2f)\n", fName[minIndex], lName[minIndex], costs[minIndex]); System.out.printf("Average: %.2f\n", average); } }
修正点说明
- 把
costs[i] = price * numItemBought改成costs[j] += price * numItemBought,确保累加当前顾客的总消费。 - 商品遍历范围从
numItems改成count,保证能找到所有商品。 - 找最值时不再排序数组,而是记录最值的索引,这样能直接对应到顾客姓名。
- 用
printf格式化输出,保留两位小数,符合预期输出的格式。 - 初始化每个顾客的
costs[j]为0,避免数组默认值的干扰。
内容的提问来源于stack exchange,提问作者user13735919
相关产品推荐
相关产品推荐

