求优化:检查数组元素是否均恰好重复两次的C语言程序
优化建议与修正方案
你的程序核心逻辑可行,但在效率、严谨性和可读性上有不少可以优化的空间,以下是具体改进建议和优化后的代码:
原代码的问题点
- 用
double存储整数输入:浮点数的相等判断存在精度风险,且完全没必要,直接用int类型更合适 - 额外的
num数组冗余:可以通过更简洁的方式统计元素出现次数,不需要额外标记数组 - 时间复杂度较高:嵌套循环的O(n²)复杂度,数据量大时效率偏低
- 变量命名不清晰:
arr、p、a这类命名表意模糊,可读性差 - 缺少快速剪枝:如果数组长度
n是奇数,直接可以判定为NO,无需后续计算
优化方案1:排序后遍历检查(O(n log n)复杂度)
排序后相同元素会相邻,只需遍历一次检查每对元素是否相等即可,逻辑简单且效率更高:
#include <stdio.h> #include <stdlib.h> #define MAX_SIZE 100 // qsort的比较函数 int compare(const void *a, const void *b) { return *(int *)a - *(int *)b; } int main() { int n; // 输入数组长度,限制范围1-100 do { printf("Enter the number of array: "); scanf("%d", &n); } while (n < 1 || n > MAX_SIZE); // 快速剪枝:奇数长度直接输出NO if (n % 2 != 0) { printf("NO"); return 0; } int array[MAX_SIZE]; printf("Enter the sequence: "); for (int i = 0; i < n; i++) { scanf("%d", &array[i]); } // 排序数组 qsort(array, n, sizeof(int), compare); // 遍历检查每一对相邻元素 int valid = 1; for (int i = 0; i < n; i += 2) { if (array[i] != array[i + 1]) { valid = 0; break; } } printf(valid ? "YES" : "NO"); return 0; }
优化方案2:哈希计数法(O(n)复杂度)
如果输入的整数范围可控,用计数数组统计每个元素的出现次数,最后检查所有计数是否为2:
#include <stdio.h> #include <string.h> #define MAX_SIZE 100 // 假设输入整数范围在-50到50之间,可根据实际需求调整 #define MIN_VAL -50 #define MAX_VAL 50 int main() { int n; do { printf("Enter the number of array: "); scanf("%d", &n); } while (n < 1 || n > MAX_SIZE); if (n % 2 != 0) { printf("NO"); return 0; } int count[MAX_VAL - MIN_VAL + 1] = {0}; int num; printf("Enter the sequence: "); for (int i = 0; i < n; i++) { scanf("%d", &num); // 超出预设范围直接判定无效 if (num < MIN_VAL || num > MAX_VAL) { printf("NO"); return 0; } count[num - MIN_VAL]++; } int valid = 1; for (int i = 0; i < MAX_VAL - MIN_VAL + 1; i++) { if (count[i] != 0 && count[i] != 2) { valid = 0; break; } } printf(valid ? "YES" : "NO"); return 0; }
关键优化说明
- 类型修正:将
double改为int,避免浮点数比较的精度问题,同时节省内存 - 快速剪枝:先判断
n是否为偶数,奇数直接返回NO,减少不必要的计算 - 效率提升:排序法将时间复杂度从O(n²)降到O(n log n),哈希计数法达到O(n)
- 可读性优化:变量命名更清晰,比如用
valid代替p,MAX_SIZE代替模糊的arr - 逻辑简化:去掉冗余的
num数组,用更直接的方式统计或验证元素出现次数
内容的提问来源于stack exchange,提问作者Hzastack
相关产品推荐
相关产品推荐

