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

如何将数组重复元素复制到另一数组并获取目标数组长度?

解决C语言中复制重复元素到目标数组并获取有效长度的问题

原代码存在的问题

  • copy_duplicates函数逻辑错误:找到重复元素时直接用原数组索引i给dst[i]赋值,会导致目标数组出现大量未初始化的空位,且同一个重复元素会被多次计数(比如原数组中的6出现两次,会被重复统计)。
  • 主函数中int dst[?lenghtdst];写法非法:C语言里静态数组的大小必须是编译期常量,不能用运行时变量定义。
  • 主函数未初始化变量i,直接进入循环会触发未定义行为。
  • 未接收copy_duplicates的返回值,无法获取目标数组的有效元素个数。

解决方案1:先统计数量再填充数组

分两步处理:先遍历源数组统计去重后的重复元素数量,再创建足够大的目标数组并填充元素。

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

// 统计去重后的重复元素个数
size_t count_duplicates(const int src[], size_t len) {
    size_t count = 0;
    bool added[len]; // C99变长数组,不支持的话可以用malloc动态分配
    memset(added, 0, sizeof(added));

    for (size_t i = 0; i < len; i++) {
        if (added[i]) continue; // 跳过已统计过的重复元素
        bool is_duplicate = false;
        for (size_t d = i + 1; d < len; d++) {
            if (src[i] == src[d]) {
                is_duplicate = true;
                added[d] = true; // 标记后续重复元素,避免重复统计
            }
        }
        if (is_duplicate) count++;
    }
    return count;
}

// 复制去重后的重复元素到目标数组
size_t copy_duplicates(int dst[], const int src[], size_t len) {
    size_t idx = 0;
    bool added[len];
    memset(added, 0, sizeof(added));

    for (size_t i = 0; i < len; i++) {
        if (added[i]) continue;
        bool is_duplicate = false;
        for (size_t d = i + 1; d < len; d++) {
            if (src[i] == src[d]) {
                is_duplicate = true;
                added[d] = true;
            }
        }
        if (is_duplicate) dst[idx++] = src[i];
    }
    return idx;
}

int main(void) {
    const int src[] = {6, 4, 6, 4};
    size_t src_len = sizeof(src) / sizeof(src[0]);
    
    // 第一步:统计重复元素数量
    size_t dst_len = count_duplicates(src, src_len);
    // 创建目标数组(C99变长数组,不支持则用malloc)
    int dst[dst_len];
    
    // 第二步:复制元素并获取实际填充长度
    size_t actual_len = copy_duplicates(dst, src, src_len);

    // 输出结果
    for (size_t i = 0; i < actual_len; i++) {
        printf("%d ", dst[i]);
    }
    printf("\n");

    return 0;
}

解决方案2:动态分配目标数组内存

在函数内部分配内存,返回目标数组指针,同时通过指针参数传递有效长度,无需主函数提前知道数组大小。

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

// 动态分配内存并复制重复元素,返回数组指针,有效长度通过out_len输出
int* copy_duplicates(const int src[], size_t len, size_t* out_len) {
    *out_len = 0;
    bool* added = malloc(len * sizeof(bool));
    if (!added) return NULL;
    memset(added, 0, len * sizeof(bool));

    // 先统计重复元素数量
    for (size_t i = 0; i < len; i++) {
        if (added[i]) continue;
        bool is_duplicate = false;
        for (size_t d = i + 1; d < len; d++) {
            if (src[i] == src[d]) {
                is_duplicate = true;
                added[d] = true;
            }
        }
        if (is_duplicate) (*out_len)++;
    }

    // 分配目标数组内存
    int* dst = malloc(*out_len * sizeof(int));
    if (!dst) {
        free(added);
        return NULL;
    }

    // 填充目标数组
    size_t idx = 0;
    memset(added, 0, len * sizeof(bool)); // 重置标记
    for (size_t i = 0; i < len; i++) {
        if (added[i]) continue;
        bool is_duplicate = false;
        for (size_t d = i + 1; d < len; d++) {
            if (src[i] == src[d]) {
                is_duplicate = true;
                added[d] = true;
            }
        }
        if (is_duplicate) dst[idx++] = src[i];
    }

    free(added);
    return dst;
}

int main(void) {
    const int src[] = {6, 4, 6, 4};
    size_t src_len = sizeof(src) / sizeof(src[0]);
    size_t dst_len;
    int* dst = copy_duplicates(src, src_len, &dst_len);

    if (dst) {
        for (size_t i = 0; i < dst_len; i++) {
            printf("%d ", dst[i]);
        }
        printf("\n");
        free(dst); // 记得释放动态分配的内存
    }

    return 0;
}

注意事项

  • 方案1的变长数组(VLA)需要编译器支持C99标准,不支持的话可以替换为malloc动态分配。
  • 方案2必须记得释放动态分配的内存,避免内存泄漏。
  • 两种方案都解决了原代码中重复计数、目标数组长度未知的问题,能正确获取目标数组的有效元素个数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 20:20:31