【问题标题】:Checking for duplicate letters in an array in C在C中检查数组中的重复字母
【发布时间】:2021-06-28 07:00:39
【问题描述】:

我想知道为什么我的重复检查给了我错误的输出。这个想法是建立一个嵌套循环,将数组中的每个后续字母与初始循环的字母进行比较。但是,如果我打印结果,该函数会在 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 时返回 true”是什么意思?什么“功能”?什么是“真”?请尝试创建一个适当的minimal reproducible example 向我们展示并告诉我们您提供的输入以及预期和实际输出。
  • 也许您还应该花一些时间来刷新 SO tour、阅读 How to Ask 以及 this question checklist
  • 应该是if (argv[1][n] == argv[1][i])。此外,i 应该以int i=n+1 开头

标签: c for-loop duplicates string-comparison c-strings


【解决方案1】:

这些 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 == '\0';
}

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." );

【讨论】:

    【解决方案2】:

    一种更有效的方法来检查字符串中的重复字符。只需要一个 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;
        }
    } 
    

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 2021-10-04
        • 1970-01-01
        • 2020-12-16
        • 2016-07-06
        • 1970-01-01
        • 1970-01-01
        • 2015-06-14
        • 2019-06-28
        • 1970-01-01
        相关资源
        最近更新 更多