删除数组中的迭代时出现问题

Trouble deleting iterations in array

本文关键字:问题 迭代 数组 删除      更新时间:2023-10-16

在此代码中,我尝试从数组中删除指定值的所有出现次数。 函数应该有三个参数,数组、数组长度和要搜索的值。每次找到该值时,都应移动数组以删除该值。

这是我到目前为止所拥有的:

void arrayShift(int arr[], int length, int value){
   for(int i = 0; i<length; i++)
       {
       if(arr[i] == value)
           {
            for (int k = i; k<length ; k++)
               {
                   arr[k] = arr[k+1];
               }
           arr[length-1] = 0;
           }
        }
}

当使用以下值时,代码成功:

int inputarray[] = {10,20,30,40,50,10};
int length = 6;
int value = 10;
//output: 20 30 40 50
int inputarray[] = {6, 7, 8, 9}; 
int length = 4;
int value = 6;
//ouput: 7 8 9
int inputarray[] = {10,20,30,40,50,60}; 
int length = 6;
int value = 70;
//output: 10 20 30 40 50 60

但是,在以下情况下,代码不起作用:

int inputarray[] = {9,8,9,9,9,9,6}; 
int length = 7;
int value = 9;
//what I get: 8 9
//what I want: 8 6

我似乎无法弄清楚为什么我的代码在迭代时失败。

扫描阵列并将不同于value的项目复制到数组的开头。
变量 j 是一个副本目标索引,因此它会在每个副本上递增。
j 的最终值是复制的项目数,即生成的数组长度 – 返回它,以便调用方知道它可能使用arr[]的哪个部分。

int arrayShift(int arr[], int length, int value){
    int j = 0;
    for(int i = 0; i<length; i++)
        if(arr[i] != value)
            arr[j++] = arr[i];
    /* you may also zero the tail of array,
       but it doesn't seem necessary if you return j
    */
    for(i=j; i<length; i++)
        arr[i] = 0;
    return j;   // new length
}
这是

你的O(n^2)算法固定的。有关线性复杂性,请参阅CiaPan的答案。

void arrayShift(int arr[], int length, int value)
{
    for(int i = 0; i < length; i++)
    {
        if(arr[i] == value)
        {
             for (int k = i; k < length ; k++) // condition should be k + 1 < length, otherwise k + 1 is out of bounds
                 arr[k] = arr[k + 1];
             i--;      // you want to decrement i here cause current element has been removed, thus i is already index of the next element
             length--; // you should also decrement length
             arr[length] = 0;
        }
    }
}

您还应该返回新的长度,或通过引用传递长度以了解之后的大小...

i = 1数组{8,9,9,9,9,6,0}并且array[i]正在查看第一个9时。

i = 2数组{8,9,9,9,6,0,0}并且array[i]正在查看第二个9时。

由于i只会从这一点向前移动,因此无法使用当前函数摆脱数组中的第一个9

问题就像阿扎鲁桑所说,

让我们解释一下。

对于代码

int inputarray[] = {9,8,9,9,9,9,6}; 
int length = 7;
int value = 9;

对于i=0arr[i] 9,它被交换,数组变为

8 9 9 9 9 6
^
i=0

现在对于i=1arr[i] 9并被交换。交换后的阵列变为

8 9 9 9 6
  ^
  i=1

但是,它转到下一个i=2,这会导致跳过索引1处的9。在索引 2 交换9后,数组变为

8 9 9 6
    ^
    i=2

如您所见,i=1处的9没有改变。这就是导致问题的原因。

要解决此问题,只需添加i--,如下所示

void arrayShift(int arr[], int length, int value){
   for(int i = 0; i<length; i++)
       {
       if(arr[i] == value)
           {
            for (int k = i; k<length ; k++)
               {
                   arr[k] = arr[k+1];
               }
           arr[length-i] = 0;   // I changed to length - i
           i--;                 // added i--
           }
        }
}

嗯,这应该可以解决问题。

你犯了一个常见的错误:你习惯于用for循环遍历数组,以至于你还没有真正考虑过你在做什么。

如果您的阵列是这个

1 2 3 4
  ^

并且您正在查看指示的元素,如果您不想删除它,请前进

1 2 3 4
    ^

但是,如果要删除它,请将数组更改为

1 3 4
  ^

现在你不想前进,因为你已经在下一个元素了。

因此,您必须创建一个与平时不同的循环结构(您可能希望使用 while ),以便您只能在不删除元素时才告诉它前进。