回顾:从数组中删除重复项

review: remove duplicate from an array

我想出了一个从数组中删除重复项的代码,并希望它检查错误(例如,对数组索引使用 sizeof 是否可以)?

#include <stdio.h>
#include <stddef.h>
#include <stdint.h>

int main()
{
        int a[] = {1,2,4,4,5,6,2,7, INT32_MAX};
        int flag[sizeof(a)] = {0}, i=0,j=0; 

        while (a[i] != INT32_MAX ) {
                 if(a[i] != a[i+1])
                        a[j++] = a[i];
#if 0
                if(0 == flag[a[i]]) {
                        flag[a[i]] = 1;
                        a[j++] = a[i];
                }
#endif
        i++;
        }

        for (i =0;i<j;i++)
                printf("%d\n", a[i]);
};

这个数组的初始化

int a[] = {1,2,4,4,5,6,2,7, INT32_MAX};

没有意义。一般来说,类型 int 可以与类型 int32_t 不同。所以不清楚为什么这个值出现在初始化列表中以及为什么代码依赖于这个值。

要删除整数数组中的重复元素,不需要标记值。

此外,在您的代码中,由于 while 循环中的条件,值 INT32_MAX 不会出现在结果子数组中

while (a[i] != INT32_MAX ) {

通常字符数组中可以不存在标记值。

一般来说a[i]也可以大于sizeof( a )。所以这个 if 语句

if(0 == flag[a[i]])

没有意义,可以调用未定义的行为。

代码可以如下所示

int a[] = {1,2,4,4,5,6,2,7 };
const size_t N = sizeof( a ) / sizeof( *a );

size_t n = 0;

for ( size_t i = 0; i != N; i++ )
{
    size_t j = 0;

    while ( j != n && a[j] != a[i] ) j++;

    if ( j == n ) a[n++] = a[i];
}

for ( size_t i = 0; i != n; i++ )
{
    printf( "%d ", a[i] );
}
putchar( '\n' );

这是一个演示程序

#include <stdio.h>

int main( void ) 
{
    int a[] = {1,2,4,4,5,6,2,7 };
    const size_t N = sizeof( a ) / sizeof( *a );

    size_t n = 0;

    for ( size_t i = 0; i != N; i++ )
    {
        size_t j = 0;

        while ( j != n && a[j] != a[i] ) j++;

        if ( j == n ) a[n++] = a[i];
    }

    for ( size_t i = 0; i != n; i++ )
    {
        printf( "%d ", a[i] );
    }
    putchar( '\n' );    

    return 0;
}

程序输出为

1 2 4 5 6 7 

如果你想在写for循环时使用标记值

for ( size_t i = 0; i != N && a[i] != SentinelValue; i++ )

其中 SentinelValue 是某个值。

然后在循环之后你应该写

a[n++] = SentinelValue;