数组过滤盈利摊位异常排查:仅排除一个负盈利项问题求助
问题分析与解决
嘿,我发现你这段删除负盈利摊位的代码里藏着一个经典的循环索引bug!正是这个问题导致你只排除了一个负盈利摊位,剩下的没被过滤掉。
错误原因
当你删除第i个负盈利元素后,后面的所有元素都会向前挪动一位(通过内层的j循环),同时n也减了1。但这时候外层循环的i会继续递增,这就跳过了现在处于i位置的新元素——也就是原来的i+1位置的元素。举个例子:
假设数组里有连续两个负盈利摊位,索引0和1都是负数。当你删掉索引0的元素后,索引1的元素会移到索引0的位置,但接下来
i变成1,直接跳过了现在索引0的这个负盈利元素,导致它没被检查到,最后就留在数组里了。
修正方案
你有两种简单的方式修复这个问题:
方案1:调整循环索引
在删除元素后,让i回退一位,这样下一次循环会重新检查当前位置的新元素:
for (int i = 0; i < n; i++){ if (Stalls[i].net < 0){ for (int j = i + 1; j < n; ++j){ Stalls[j - 1] = Stalls[j]; } n--; i--; // 删除后回退索引,避免跳过下一个元素 } }
方案2:改用while循环控制索引
用while循环可以更直观地控制什么时候移动索引:
int i = 0; while (i < n) { if (Stalls[i].net < 0) { // 前移元素覆盖当前负盈利摊位 for (int j = i + 1; j < n; ++j) { Stalls[j - 1] = Stalls[j]; } n--; // 不移动i,继续检查当前位置的新元素 } else { i++; // 只有当前元素符合条件时,才移动到下一个 } }
进阶优化:双指针法(更高效)
如果摊位数量较多,上面的方式每次删除都要移动大量元素,效率不高。可以用双指针法,只遍历一次数组就完成过滤:
int validCount = 0; for (int i = 0; i < n; ++i) { if (Stalls[i].net >= 0) { // 把符合条件的元素移到前面的有效位置 Stalls[validCount++] = Stalls[i]; } } n = validCount; // 更新有效元素的数量
验证效果
修正后再执行后续的排序和输出逻辑,就能正确只保留盈利(net≥0)的摊位,并且按盈利额从小到大排序输出啦。
内容的提问来源于stack exchange,提问作者Anna
相关产品推荐
相关产品推荐

