Java序号递增逻辑Bug排查:分数相同时编号显示异常
Hey there! Let's break down why your numbering is glitching when there are duplicate scores, and fix it step by step.
The Root Cause
Your current code increments the b (numbering counter) once per iteration of the main loop, but when there are multiple entries with the same max score (like Saniya and Andrey both with 75), your printMax method outputs multiple lines using the same number.
Here's the play-by-play of what's going wrong:
- When processing the 75 score,
printMaxruns twice for the two matching entries, but uses the sameordervalue (4) for both. - The main loop only increments
bby 1 afterprintMaxfinishes, so the next entry (Daulet) gets number 5 instead of 6.
On top of that, your getMax method starts with max = 0 which would fail if any scores are negative, and the way you're removing elements in printMax can cause index shifting issues that skip entries.
The Fix
Let's adjust the numbering logic, fix the max calculation, and handle element removal safely:
Step 1: Update getMax to handle all score values
Change the initial max value to Integer.MIN_VALUE so it works even with negative scores, and use proper generics to avoid messy casting:
public static int getMax(ArrayList<Integer> list) { int max = Integer.MIN_VALUE; for(int score : list) { if (score > max) { max = score; } } return max; }
Step 2: Rewrite printMax to track and increment numbers correctly
Modify printMax to count how many entries it processes, use continuous numbering for duplicates, and safely remove elements without index errors:
public static int printMax(int score, ArrayList<String> names_unsorted, ArrayList<Integer> scores_unsorted, int startOrder) { int entriesProcessed = 0; ArrayList<Integer> indicesToRemove = new ArrayList<>(); // First, collect all indices matching the target score for (int i = 0; i < scores_unsorted.size(); i++) { if (scores_unsorted.get(i) == score) { // Calculate the correct number for this entry System.out.println((startOrder + entriesProcessed) + ") " + names_unsorted.get(i) + ": " + score); indicesToRemove.add(i); entriesProcessed++; } } // Remove elements from the end to avoid index shifting issues for (int i = indicesToRemove.size() - 1; i >= 0; i--) { int idx = indicesToRemove.get(i); scores_unsorted.remove(idx); names_unsorted.remove(idx); } return entriesProcessed; }
Step 3: Adjust the main loop to use the entry count
Replace the for loop with a while loop (since we don't know how many entries we'll process each iteration) and update the counter by the number of entries processed:
public static void main(String[] args) { Scanner input = new Scanner(System.in); int num = input.nextInt(); ArrayList<Integer> scores_unsorted = new ArrayList<>(); ArrayList<String> names_unsorted = new ArrayList<>(); for (int i = 0; i < num; i++) { String name = input.next(); int score = input.nextInt(); scores_unsorted.add(score); names_unsorted.add(name); } int currentOrder = 1; // Loop until all entries are processed while (!scores_unsorted.isEmpty()) { int currentMax = getMax(scores_unsorted); int processed = printMax(currentMax, names_unsorted, scores_unsorted, currentOrder); // Update the order counter by how many entries we just printed currentOrder += processed; } input.close(); }
Why This Works
- Continuous Numbering: Each duplicate score entry gets its own sequential number by adding the
entriesProcessedcounter to the starting order. - Safe Removal: Collecting indices first and removing from the end prevents index shifting that would skip elements or cause errors.
- Robust Max Calculation: Using
Integer.MIN_VALUEensures we handle all possible integer scores, including negatives.
When you run this with your input, you'll get the expected output:
- Zeynep: 100
- Abay: 96
- Berik: 78
- Saniya: 75
- Andrey: 75
- Daulet: 45
内容的提问来源于stack exchange,提问作者Kas

