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]); // 应该打印返回结构体中的数组,而非原数组 } }
- 未初始化变量k:
arr[k]=arr[k+1];中的k未赋值,属于未定义行为,会导致随机内存访问错误。 - 错误的数组长度修改逻辑:无论是否找到重复元素,都执行
len--和count++,直接破坏数组长度的正确性。 - 内层循环重置错误:
j=i强制将内层循环拉回i的位置,导致重复检查、逻辑混乱甚至无限循环。 - main函数打印错误:打印原数组
arr而非函数返回的Numbers结构体中的n->arr,不符合函数设计逻辑。
你的解决方案的遗留问题
你补全了元素移动的循环,但仍存在关键错误:
// 你的代码中if块的缩进错误,导致以下代码不在if判断内 len=len-1; count=count+1; j=i;
- 缩进错误导致逻辑失控:
len--、count++、j=i未包含在if(arr[j]==arr[i])的代码块中,意味着无论是否找到重复,都会执行这些操作,直接导致数组被错误缩短。 - 内层循环重置错误:找到重复后执行
j=i,会让内层循环回到i的位置,重复检查已处理过的元素,且跳过后续未检查的元素。 - 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的内存,避免泄漏 }
关键修改点
- 修正缩进逻辑:将
len--、count++、j--放入if代码块内,仅在找到重复元素时执行。 - 内层循环调整:用
j--替代j=i,删除重复元素后,回退j的位置,检查当前位置的新元素(因为后续元素前移了一个位置)。 - 修正打印逻辑:打印返回的
Numbers结构体中的n->arr,而非原数组。 - 添加内存释放:main函数中
free(n)避免内存泄漏,符合C语言规范。
内容的提问来源于stack exchange,提问作者Mohd Gaming
相关产品推荐
相关产品推荐

