我对编程还很陌生,我写了一段代码从逻辑上删除重复项,从逻辑上讲,它应该可以工作,但是没有...。我对它进行了多次逻辑测试,这很有意义...
这是代码:
#include <stdio.h>
int rmDuplicates(int arr[], int n)
{
int i, j;
for (i = 0; i < n; i++) {
if (arr[i] == arr[i + 1]) {
for (j = i + 1; j < n - 1; j++) {
arr[j] = arr[j + 1];
}
n--;
}
return n;
}
}
int main()
{
int n, i;
scanf("%d", &n);
int arr[n];
for (i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
n = rmDuplicates(arr, n);
for (i = 0; i < n; i++) {
printf("%d", arr[i]);
}
printf("\n%d", n);
return 0;
}
答案 0 :(得分:2)
您的“ return n”在错误的位置,并且在第一个循环之后返回。
for(i=0;i<n;i++) {
if(arr[i] == arr[i+1]) {
for(j=i+1;j<n-1;j++) {
arr[j] = arr[j+1];
}
n--;
}
return n; // <---- this
}
// <-- should be here.
作为确认,如果我将return n;
移到循环外,代码将起作用。但是,它只会删除连续重复项,因为您只能对照连续的arr [i + 1]检查arr [i]。
(此外,循环应该在n-1处停止,因为否则arr [n-1 + 1]是数组之外的arr [n]。
最后一个问题是,如果您有
n
...5,..., 5, 5, 6
i j
,然后将第一个5与第二个进行比较,找到一个重复的副本,然后将所有后续内容移动一步,在第j个位置您将再次拥有5,但是j现在将递增,您将将第一个5与第6个进行对比,而不是第三个5,则未找到重复项:
n
...5,..., 5, 6
i j
由于这个原因,当找到匹配项时,您需要将j倒回一并重复该测试:
int rmDuplicates(int arr[], int n) {
int i,j,k;
for (i=0;i<n-1;i++) {
for (j=i+1; j < n; j++) {
if(arr[i] == arr[j]) {
n--;
for (k=j;k<n;k++) {
arr[k] = arr[k+1];
}
j--;
}
}
}
return n;
}
从性能的角度来看,上述算法为O(n ^ 2),也就是说,如果数组列表增加一倍,则该算法所花费的时间是原来的四倍。如果加倍,则需要9倍的时间。
因此,更好的算法是首先对数组进行原位排序,以使1 3 2 7 2 3 5
变成1 2 2 3 3 5 7
(这花费了O(n log n),并且增长得更慢);那么您只需“压缩”跳过重复项的数组,即O(n)并得到1 2 3 5 7
int i, j;
for (i = 0, j = 1; j < n;) {
if (arr[i] == arr[j]) {
j++;
continue;
}
i++;
if (j != (i+1)) {
arr[i] = arr[j];
}
j++;
}
n = i+1;
答案 1 :(得分:1)
size_t removeDups(int *arr, size_t size)
{
if(arr && size > 1)
{
for(size_t current = 0; current < size - 1; current++)
{
size_t original_size = size;
size_t copypos = current + 1;
for(size_t cpos = current + 1; cpos < original_size; cpos++)
{
if(arr[current] == arr[cpos])
{
if(cpos < original_size -1)
{
if(arr[current] != arr[cpos + 1])
{
arr[copypos++] = arr[cpos + 1];
cpos++;
}
}
size--;
}
else
{
arr[copypos++] = arr[cpos];
}
}
}
}
return size;
}
int main(void)
{
int arr[] = {1,1,1,2,2,3,3,4,5,6,7,1,8,8,2,2,2,2};
size_t size = sizeof(arr) / sizeof(arr[0]);
size = removeDups(arr, size);
for(size_t index = 0; index < size; index++)
{
printf("%d\n", arr[index]);
}
}