检查 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." );
我想知道为什么我的重复检查给出了错误的输出。这个想法是构建一个嵌套循环,将数组中的每个后续字母与初始循环的字母进行比较。但是,如果我打印结果,该函数会在 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." );