为何我的for循环中count等于CardReduce长度的分支不执行?
问题描述
我写了一段基于随机生成数组的for循环代码,预期逻辑如下:
- 将原数组长度存入
ArrayCount集合 - 每次循环遍历数组元素并减1,
count自增,移除值为0的元素 - 当
count等于CardReduce的长度时,添加存储的数组长度、排序集合、清空存储长度以进入下一轮循环
但判断count == CardReduce.size()的分支始终未执行,导致结果错误。例如输入随机数组[2,2,7,9,25],预期第一轮结束后得到[1,1,6,8,24,5],实际得到[4,5,6,22],只有原数组长度5是正确的,其余结果完全错误。
核心循环代码
for (int i = 0; EndResult == true; i++) { count = count + 1; if (count == 1) {//adds size of arraylist to arraycount ArrayCount.add(CardReduce.size()); } for (int a = 0; a < CardReduce.size(); a++) {//replaces values by same value - 1 int val = CardReduce.get(a); CardReduce.set(a, (val -1)); } for (int b = 0; b < CardReduce.size(); b++) {//removes all elements with value of 0 CardReduce.remove(Integer.valueOf(0)); } if (count == CardReduce.size()) {//when count is equal to size of CardReduce executes CardReduce.addAll(ArrayCount); Collections.sort(CardReduce); System.out.println(CardReduce); ArrayCount.clear(); count = 0; } if (count == 8) { EndResult = false; } }
完整简化代码
import java.util.*; public class test { public static void main(String[] args) { int[] EndResult = {1, 2, 3, 4, 5, 6, 7, 8, 9}; int[] RandomCards = new int[45]; int Size = 0; int total = 45; int count = 0; for(int i = 0; total > 0; i++) { int random = (int) (Math.random() * total) + 1; total -= random; RandomCards[i] = random; Size++; Arrays.sort(RandomCards); } System.out.println("Cards Seperated in Stacks: "); for (int i = 0; i < RandomCards.length; i++) { if (RandomCards[i] > 0) { System.out.print(RandomCards[i] + " "); } } System.out.println(" "); System.out.println("=========================="); System.out.println("Game Start: "); ArrayList<Integer> CardReduce = new ArrayList<Integer>(); ArrayList<Integer> ArrayCount = new ArrayList<Integer>(); Boolean FinalResult = true; count = 0; for(int i = 0; i < RandomCards.length; i++) { if (RandomCards[i] > 0) { CardReduce.add(RandomCards[i]); } } for (int i = 0; FinalResult == true; i++) { count = count + 1; if (count == 1) {//adds size of arraylist to arraycount ArrayCount.add(CardReduce.size()); } for (int a = 0; a < CardReduce.size(); a++) {//replaces values by same value - 1 int val = CardReduce.get(a); CardReduce.set(a, (val -1)); } for (int b = 0; b < CardReduce.size(); b++) {//removes all elements with value of 0 CardReduce.remove(Integer.valueOf(0)); } if (count == CardReduce.size()) {//when count is equal to size of CardReduce executes CardReduce.addAll(ArrayCount); Collections.sort(CardReduce); System.out.println(CardReduce); ArrayCount.clear(); count = 0; } if (count == 8) { FinalResult = false; } } } }
问题原因及解决方案
1. 移除0元素的循环逻辑错误
你使用for (int b = 0; b < CardReduce.size(); b++)遍历并移除0元素时,每次移除元素会导致集合长度缩短,同时索引b自增,会跳过部分未检查的元素。比如集合为[0,0,1],第一次移除索引0的0后,集合变为[0,1],b自增到1,此时访问索引1的元素是1,会漏掉剩余的0,导致CardReduce.size()计算不准确,进而无法触发目标分支。
修复方法:使用迭代器安全移除元素,或者倒序遍历:
// 方法1:迭代器方式(推荐) Iterator<Integer> iterator = CardReduce.iterator(); while (iterator.hasNext()) { if (iterator.next() == 0) { iterator.remove(); } } // 方法2:倒序遍历 for (int b = CardReduce.size() - 1; b >= 0; b--) { if (CardReduce.get(b) == 0) { CardReduce.remove(b); } }
2. count与CardReduce.size()的触发时机不匹配
你在每次循环先让count++,再修改CardReduce(元素减1、删除0),最后判断count == CardReduce.size()。但CardReduce的长度在每次循环后都会动态变化,而count是线性递增的,几乎不可能刚好相等。
按照你的预期逻辑,应该用固定的原数组长度作为触发条件,而不是动态变化的CardReduce.size()。修改方式如下:
// 在循环外先保存初始数组长度 int originalSize = CardReduce.size(); // 循环内修改判断条件 if (count == originalSize) { CardReduce.addAll(ArrayCount); Collections.sort(CardReduce); System.out.println(CardReduce); ArrayCount.clear(); count = 0; // 若需要进入下一轮,更新初始长度为当前集合的新长度 originalSize = CardReduce.size(); }
3. 元素减1循环的隐患
虽然当前元素减1的循环是先遍历所有元素再删除0,暂时不会出问题,但如果后续逻辑调整,遍历过程中集合长度变化会导致索引越界。建议先获取固定长度再遍历:
int currentSize = CardReduce.size(); for (int a = 0; a < currentSize; a++) { int val = CardReduce.get(a); CardReduce.set(a, val - 1); }
内容的提问来源于stack exchange,提问作者Kuro Zuroz
相关产品推荐
相关产品推荐

