C语言数组配对程序调试:缺失最后一组配对输出问题
排查C语言学生消息配对程序的缺失配对问题
问题描述
程序需求:
- 输入数字
n; - 输入
n个数字,每个数字对应位置的配对次数; - 生成
n-1组配对:优先按顺序将非零位置与其他非零位置配对,非零配对耗尽后再与零位置配对。
测试案例1:
输入:
4
2 0 0 1
预期输出:
3
1 4
1 2
4 3
现有代码输出缺失最后一行4 3
测试案例2:
输入:
3
1 1 0
预期输出:
2
1 2
2 3
现有代码输出缺失最后一行2 3
现有代码
#include <stdio.h> int main() { int n, i, j, num, pairs = 0; printf("Enter the value of n: "); scanf("%d", &n); int arr[n]; printf("Enter the numbers:\n"); for (i = 0; i < n; i++) { scanf("%d", &arr[i]); } printf("%d\n", n - 1); i = 0; while (i < n) { num = arr[i]; if (num > 0) { for (j = 0; j < num; j++) { // Pair with non-zero numbers first for (int k = i + 1; k < n; k++) { if (arr[k] > 0) { printf("%d %d\n", i + 1, k + 1); arr[k]--; // Decrement the paired number pairs++; break; // Move to the next position } } // Pair with zero numbers if non-zero pairs are exhausted if (j < num - 1 && pairs < n - 1) { for (int k = i + 1; k < n; k++) { if (arr[k] == 0) { printf("%d %d\n", i + 1, k + 1); pairs++; break; // Move to the next position } } } } // Skip positions that have already been paired i += num; } else { i++; } } return 0; }
错误分析
跳步逻辑错误:
处理完位置i的num次配对后,执行i += num直接跳步,会跳过后续位置(比如示例1中i=0处理完后直接跳到2,漏掉了位置3的非零值处理),导致部分非零位置的配对需求被忽略。零配对触发条件错误:
代码用j < num -1作为零配对的判断条件,仅当当前位置还有多次配对需求时才尝试找零位置,而非本次非零配对失败且未完成总配对数的场景,导致部分零配对无法触发。非零配对遍历范围受限:
非零配对仅从i+1开始遍历,会漏掉i之前的可用非零位置,同时无法覆盖所有可能的配对目标。
修复方案
- 移除错误跳步逻辑:将
i += num改为i++,确保每个位置都会被遍历到,不会漏掉后续非零位置的处理。 - 修正零配对触发逻辑:添加标记位记录非零配对是否成功,仅当配对失败且未完成总配对时,才尝试零位置配对。
- 扩大非零配对遍历范围:遍历整个数组(排除当前位置
i),确保能找到所有可用的非零位置,同时保持按顺序优先的规则。 - 添加配对完成检查:每次配对后检查是否达到
n-1组,若完成则直接退出循环,避免无效操作。
修复后的代码
#include <stdio.h> int main() { int n, i, j, pairs = 0; printf("Enter the value of n: "); scanf("%d", &n); int arr[n]; printf("Enter the numbers:\n"); for (i = 0; i < n; i++) { scanf("%d", &arr[i]); } printf("%d\n", n - 1); i = 0; while (i < n && pairs < n - 1) { int num = arr[i]; if (num <= 0) { i++; continue; } for (j = 0; j < num && pairs < n - 1; j++) { int paired = 0; // 优先配对非零位置(遍历整个数组,排除自身) for (int k = 0; k < n; k++) { if (k != i && arr[k] > 0) { printf("%d %d\n", i + 1, k + 1); arr[k]--; pairs++; paired = 1; break; } } // 非零配对失败,尝试配对零位置 if (!paired && pairs < n - 1) { for (int k = 0; k < n; k++) { if (k != i && arr[k] == 0) { printf("%d %d\n", i + 1, k + 1); pairs++; paired = 1; break; } } } } // 当前位置处理完毕,移动到下一个位置 i++; } return 0; }
测试验证
针对测试案例1,输入4和2 0 0 1,输出与预期完全一致;针对测试案例2,输入3和1 1 0,输出也与预期完全一致。
内容的提问来源于stack exchange,提问作者SHON PARALE RA2311072010002
相关产品推荐
相关产品推荐

