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

CTS招聘笔试题:数组去重代码修复问题咨询

CTS招聘笔试数组去重问题排查与修复

问题背景

题目要求:基于给定的错误代码,不修改原思路、不使用额外库,实现数组去重(仅保留元素首次出现)。原代码及修改后的代码均存在问题,仅部分测试用例生效。


原错误代码的核心问题

#include<stdio.h>
#include<stdlib.h>
typedef struct node {
    int arr[1000];
    int len;
} Numbers;
void* deleteDuplicate (int *arr, int len)
{
    int count=0,p,i,j,k,originalLength=len;
    for(i=0; i<len; i++)
    {
        for(j=i+1; j<len; j++)
        {
            if(arr[j]==arr[i])
            {
                arr[k]=arr[k+1]; // k未初始化,内存访问未定义
            }
            // 无论是否找到重复,都缩短数组长度,逻辑完全错误
            len=len-1;
            count=count+1;
            j=i; // 强制重置内层循环,导致逻辑混乱
        }
    }

    int  newLength = originalLength-count;
    Numbers *numbers = malloc(sizeof(*numbers));
    for(i=0; i<newLength; i++)
        numbers->arr[i]=arr[i];
    numbers->len = newLength;
    return numbers;
}

int main() {
    int arr[]={2,3,2,2,5,6,6,7};
    Numbers *n = deleteDuplicate(arr,8);
    for(int i=0;i<n->len;i++){
        printf("%d ",arr[i]); // 应该打印返回结构体中的数组,而非原数组
    }
}
  1. 未初始化变量k:arr[k]=arr[k+1];中的k未赋值,属于未定义行为,会导致随机内存访问错误。
  2. 错误的数组长度修改逻辑:无论是否找到重复元素,都执行len--和count++,直接破坏数组长度的正确性。
  3. 内层循环重置错误:j=i强制将内层循环拉回i的位置,导致重复检查、逻辑混乱甚至无限循环。
  4. main函数打印错误:打印原数组arr而非函数返回的Numbers结构体中的n->arr,不符合函数设计逻辑。

你的解决方案的遗留问题

你补全了元素移动的循环,但仍存在关键错误:

// 你的代码中if块的缩进错误,导致以下代码不在if判断内
len=len-1;
count=count+1;
j=i;
  1. 缩进错误导致逻辑失控:len--、count++、j=i未包含在if(arr[j]==arr[i])的代码块中,意味着无论是否找到重复,都会执行这些操作,直接导致数组被错误缩短。
  2. 内层循环重置错误:找到重复后执行j=i,会让内层循环回到i的位置,重复检查已处理过的元素,且跳过后续未检查的元素。
  3. count计数不准确:错误的len修改逻辑导致count无法正确统计重复元素数量,进而newLength计算错误。

符合要求的修复代码

保持原双重循环的思路,仅修正逻辑错误:

#include<stdio.h>
#include<stdlib.h>
typedef struct node {
    int arr[1000];
    int len;
} Numbers;

void* deleteDuplicate(int *arr, int len)
{
    int count = 0;
    int originalLength = len;
    int i, j, k;

    for(i = 0; i < len; i++)
    {
        for(j = i + 1; j < len; j++)
        {
            if(arr[j] == arr[i])
            {
                // 前移后续元素,覆盖重复项
                for(k = j; k < len - 1; k++)
                {
                    arr[k] = arr[k + 1];
                }
                len--;       // 数组长度减1
                count++;     // 重复元素计数加1
                j--;         // 回退j,检查当前位置的新元素(因为元素前移了)
            }
        }
    }

    int newLength = originalLength - count;
    Numbers *numbers = malloc(sizeof(*numbers));
    for(i = 0; i < newLength; i++)
    {
        numbers->arr[i] = arr[i];
    }
    numbers->len = newLength;
    return numbers;
}

int main() {
    int arr[] = {2,3,2,2,5,6,6,7};
    Numbers *n = deleteDuplicate(arr, 8);
    // 打印返回结构体中的结果数组
    for(int i = 0; i < n->len; i++)
    {
        printf("%d ", n->arr[i]);
    }
    free(n); // 释放malloc的内存,避免泄漏
}

关键修改点

  1. 修正缩进逻辑:将len--、count++、j--放入if代码块内,仅在找到重复元素时执行。
  2. 内层循环调整:用j--替代j=i,删除重复元素后,回退j的位置,检查当前位置的新元素(因为后续元素前移了一个位置)。
  3. 修正打印逻辑:打印返回的Numbers结构体中的n->arr,而非原数组。
  4. 添加内存释放:main函数中free(n)避免内存泄漏,符合C语言规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 04:18:16