You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言中数组排除唯一值时如何保留重复元素的原始顺序

解决思路与修改后的代码

你的问题核心是需要保留原数组中所有出现过至少两次的元素,并且严格维持它们在原列表中的出现顺序。原代码的问题在于没有先统计元素的出现频率,直接筛选的话要么会打乱顺序,要么会漏掉重复出现的实例。

这里提供两种可行的修改方案,从高效到灵活覆盖不同场景:

方案一:基于数组统计频率(适合元素范围可控的场景)

这种方法先遍历一次数组统计每个数字的出现次数,再重新遍历原数组,只保留那些出现次数≥2的元素,完美维持原顺序:

#include <stdio.h>
#include <stdlib.h>

// 假设元素范围在 -1000 到 1000 之间,可根据实际需求调整边界
#define MIN_VAL -1000
#define MAX_VAL 1000

int main() {
    int i, x, array[1000], result[1000];
    int count[MAX_VAL - MIN_VAL + 1] = {0}; // 初始化计数数组全为0
    int result_len = 0;

    printf("Please enter the number of integers in your list:\n");
    scanf("%d", &x);
    printf("Please enter the list of numbers:\n");
    for (i = 0; i < x; i++) {
        scanf("%d", &array[i]);
        // 处理负数的索引偏移,确保所有元素都能对应到计数数组的合法位置
        count[array[i] - MIN_VAL]++;
    }

    // 再次遍历原数组,筛选出重复出现的元素
    for (i = 0; i < x; i++) {
        if (count[array[i] - MIN_VAL] >= 2) {
            result[result_len++] = array[i];
        }
    }

    // 输出最终结果
    printf("\nThe corrected list (keeping duplicates in original order):\n");
    for (i = 0; i < result_len; i++) {
        printf("%d ", result[i]);
    }
    printf("\n");

    return 0;
}

代码说明:

  • 先通过计数数组统计每个元素的出现频率,负数元素通过偏移量转换为合法的数组索引。
  • 第二次遍历原数组时,只保留那些出现过至少两次的元素,这样完全遵循了原数组的顺序,不会打乱任何重复元素的出现位置。

方案二:基于双重循环(适合任意元素范围,无需预设边界)

如果不确定输入元素的范围,不想用固定大小的计数数组,可以用双重循环标记重复元素,同时避免重复判断:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int i, j, x, array[1000], result[1000];
    int is_duplicate[1000] = {0}; // 标记对应位置的元素是否为重复项
    int result_len = 0;

    printf("Please enter the number of integers in your list:\n");
    scanf("%d", &x);
    printf("Please enter the list of numbers:\n");
    for (i = 0; i < x; i++) {
        scanf("%d", &array[i]);
    }

    // 先标记所有重复出现的元素位置
    for (i = 0; i < x; i++) {
        if (is_duplicate[i]) continue; // 已经标记过的元素直接跳过
        int has_duplicate = 0;
        for (j = i + 1; j < x; j++) {
            if (array[i] == array[j]) {
                has_duplicate = 1;
                is_duplicate[j] = 1; // 标记后续的重复元素位置
            }
        }
        if (has_duplicate) {
            is_duplicate[i] = 1; // 标记当前元素为重复项
        }
    }

    // 按原顺序收集所有重复元素
    for (i = 0; i < x; i++) {
        if (is_duplicate[i]) {
            result[result_len++] = array[i];
        }
    }

    // 输出最终结果
    printf("\nThe corrected list (keeping duplicates in original order):\n");
    for (i = 0; i < result_len; i++) {
        printf("%d ", result[i]);
    }
    printf("\n");

    return 0;
}

代码说明:

  • 用is_duplicate数组标记每个位置的元素是否属于重复项:外层循环遍历每个元素,内层循环检查后续是否有相同元素,若有则标记当前元素和所有后续重复元素。
  • 最后遍历原数组,把所有标记为重复的元素按顺序加入结果数组,确保所有重复实例都被保留且顺序不变。

两种方案都能解决你的问题,第一种时间复杂度为O(n)效率更高,第二种无需预设元素范围,适配性更强。

内容的提问来源于stack exchange,提问作者DZtron

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:22:14