我创建了一个名为elements_n
的数组,该数组的元素为0
至N-1
,其中N
为2。下面的数字是名为{{1 }}:
elements_n
我还有一个名为0 1
的数组,其中包含以下元素:
Arr
如果数组0 1 3 1 2 4
的前3个元素中的任何一个等于Arr
的第一个元素elements_n
,我想从名为{的数组中删除该元素{1}}。然后,我对数组0
的后三个元素重复相同的过程。因此,为了更好地说明自己,我将使用以下示例:
将数组Arr
的前3个元素(分别为0、1、3和3)与Arr
的第一个元素(即0)进行比较。由于Arr
。我从数组elements_n
中删除了Arr[0] == elements_n[0]
。
比较数组Arr[0]
的后三个元素1、2、4与Arr
的第二个元素1。因为Arr
。我从数组elements_n
中删除了Arr[3] == elements_n[1]
。因此,应该在数组Arr[3]
中保留的元素是:
Arr
当我用C编程实现自己的代码时,最终结果如下:
Arr
而不是:
1 3 2 4
这是我实现的代码:
1 3 3 2 2 4
答案 0 :(得分:1)
您可以尝试类似的方法(未经测试)。
shift()
答案 1 :(得分:0)
您需要跟踪从数组中删除了多少个元素。
我的解决方案:
#include <stdio.h>
#include <stddef.h>
#include <assert.h>
#include <string.h>
size_t fancy_delete_3(const int elems[], size_t elemssize, int arr[], size_t arrsize)
{
assert(elems != NULL);
assert(arr != NULL);
assert(arrsize%3 == 0);
assert(elemssize*3 == arrsize);
// we need to count the removed elements, to know how much we need to shift left
size_t removed = 0;
// for each element in elems
for (size_t i = 0; i < elemssize; ++i) {
// check the three correponding elements in arr
for (size_t j = i*3; j < (i+1)*3; ++j) {
assert(j >= removed);
const size_t pos = j - removed;
// if elems[i] matches any of the corresponding element in arr
if (elems[i] == arr[pos]) {
// remove element at position pos
assert(arrsize >= pos + 1);
// I don't think this can ever overflow
memmove(&arr[pos], &arr[pos + 1], (arrsize - pos - 1) * sizeof(int));
++removed;
// array is one element shorter, so we can just decrease the array size
assert(arrsize > 0);
--arrsize;
}
}
}
// we return the new size of the array
return arrsize;
}
#define __arraycount(x) sizeof(x)/sizeof(x[0])
int main()
{
int elements_n[] = {0,1};
int arr[] = {0,1,3, 1,2,4};
size_t newsize = fancy_delete_3(elements_n, __arraycount(elements_n), arr, __arraycount(arr));
printf("arr size=%zu {", newsize);
for (size_t i = 0; i < newsize; ++i)
printf("%d,", arr[i]);
printf("}\n");
return 0;
}
答案 2 :(得分:0)
关于如何执行删除,您有几个相关的问题。首先,不清楚您是否了解您实际上无法从C数组中删除任何内容。您可以找到的最接近的方法是用其他方法覆盖。通常,通过将删除的一个元素之后的每个元素向前移动并减小数组的 logical 长度,可以实现从数组中进行伪删除。 * 选择了这种方法,但是(问题1)您错过了维护或更新逻辑数组长度的操作。
由于逻辑上将数组细分为段,因此您的问题变得更加复杂了,而且您似乎不欣赏您的段是可变长度的原因,如上所述删除元素时缩小。这是由于以下事实:从一个组中删除元素不会更改元素到其他组的分配。您可以在position_groups
中使用一种机制来显然地跟踪组的大小,从这个意义上说,它的名称似乎不合适。与跟踪和更新整个阵列的逻辑长度一样,您将需要跟踪和更新组的长度。
最后,您似乎在这里出现了一个错误的错误:
for (int j = index - 1; j < position_indices[count]-1; j++)
如果更好地命名position_indices
(请参见上文),则会更清楚,但要认识到它实际上包含的是每个组的 size ,以及index
和j
代表组内的索引,因此迭代的边界条件应改为j < position_indices[count]
。但是,这没有什么意义,因为无论如何您都需要一种不同的方法。
建议,然后:
* “逻辑数组大小”表示包含有意义数据的(前导)元素的数量。在您的情况下,逻辑数组大小最初与物理数组大小相同,但是每次删除元素(并因此向上移动尾部)时,逻辑大小都会减小一。
答案 3 :(得分:0)
您从未真正“删除”任何元素,只是向下移动了 每个3组的第二和第三元素。然后,当 打印,您遍历了整个数组。
数组只是连续的内存块,因此您需要一个
不同的策略。您可以使用以下方法遍历原始数组
两个索引,一个作为通用索引计数器,另一个作为
转换后的广告位的索引。如果当前元素是
与相应的elements_n
项目不同,请将其复制到
次要指标并增加它。
如果没有什么与elements_n
项相等,则只需
将数组元素重新分配给自己。但是,尽快
一个是平等的,您将利用以下优势转移他们
跟踪新尺寸。
此外,计算相应的elements_n
项很简单
将当前索引除以3的问题,因此您甚至不需要
一个额外的变量。
#include <stdio.h>
#define N 2
int main()
{
unsigned elements_n[N] = { 0, 1 };
unsigned Arr[N*3] = { 0, 1, 3, 1, 2, 4 };
int i, j;
for (i = 0, j = 0; i < N*3; i++)
if (Arr[i] != elements_n[i/3])
Arr[j++] = Arr[i];
for (i = 0; i < j; i++)
printf(" %d", Arr[i]);
printf("\n");
return 0;
}