检查 C 中数组中的重复字母

Checking for duplicate letters in an array in C

我想知道为什么我的重复检查给出了错误的输出。这个想法是构建一个嵌套循环,将数组中的每个后续字母与初始循环的字母进行比较。但是,如果我打印结果,该函数会在 A = K 时返回 true,例如我不明白这种行为。谁能解释这里发生了什么?

 for (int n = 0; n < strlen(argv[1]) ; n++)
    {
        for (int i = 0; i < strlen(argv[1]) ; i++)
        {
            if (argv[1][n] == argv[1][i + 1])
            {
                printf("argv[1][n] = %c\n", argv[1][n]);
                printf("argv[1][i] = %c\n", argv[1][i]);
                printf("Error.\n");
                return 0;
            }
        }
    }

为什么 A = K 是因为你在检查第 i+1 个索引 if (argv[1][n] == argv[1][i + 1]) 时打印第 i 个索引 printf("argv[1][i] = %c\n", argv[1][i]);。您正在打印使用 [​​=13=] 语句检查的错误字符。

此外,请注意 i+1 和您的循环条件。

检查字符串中重复字符的更有效方法。只需要一个 for 循环而不是一对嵌套循环。假定一个 8 位字符 - 因此 256 作为数组大小。

size_t table[256] = {0};
size_t positions[256] = {0};
const char* sz = argv[1];

const size_t len = strlen(argv[1]);
for (size_t i = 0; i < len; i++)
{
    unsigned char index = (unsigned char)(sz[i]);
    table[index]++;
    if (table[index] > 1)
    {
       printf("duplicate char %c found at index %d. Originally seen at index %d\n", sz[i], i, (int)(positions[index]));
       return 0;
    }
    else
    {
        positions[index] = i;
    }
} 

这些for循环

for (int n = 0; n < strlen(argv[1]) ; n++)
{
    for (int i = 0; i < strlen(argv[1]) ; i++)
    {
        if (argv[1][n] == argv[1][i + 1])
        {
            //...
        }
    }
}

没有意义,因为argv[1][n]可以和argv[1][i+1]在同一位置是同一个字母,因为内循环是从0开始的。

你还在i

位置输出一个字母
printf("argv[1][i] = %c\n", argv[1][i]);

但在前面的 if 语句中,您正在检查 i + 1.

位置的字母

循环可以如下所示

for ( size_t i = 0, n = strlen( argv[1] ); i < n ; i++ )
{
    for ( size_t j = i + 1; j < n; j++ )
    {
        if ( argv[1][i] == argv[1][j] )
        {
            printf( "argv[1][i] = %c\n", argv[1][i]);
            printf( "argv[1][j] = %c\n", argv[1][j]);
            printf("Error.\n");
            return 0;
        }
    }
}

您可以使用标准 C 函数 strchr 而不是内部循环。这是一个演示程序。

#include <stdio.h>
#include <string.h>

int unique( const char *s )
{
    while ( *s && !strchr( s + 1, *s ) ) ++s;
    
    return *s == '[=13=]';
}

int main(void) 
{
    char *s = "12345";
    
    printf( "\"%s\" -> %d\n", s, unique( s ) );
    
    s = "12341";
    
    printf( "\"%s\" -> %d\n", s, unique( s ) );

    return 0;
}

程序输出为

"12345" -> 1
"12341" -> 0

您可以调用将命令行参数作为参数传递的函数 argv[1]。例如

If ( !unique( argv[1] ) ) puts( "Error." );