如何找到字符串中的第一个重复字符?
如果输入为“ abcdexyzbwqpoolj
,则输入
输出应为b
。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int i,j;
char str[1000];
scanf("%s",str);//input the string
for( i=0;i<strlen(str);i++)
{
for(j=i+1;j<strlen(str);j++)
{
if(str[i]==str[j])//compare
{
printf("%c",str[i]);
}
}
}
}
这将打印所有重复字符,但我只想打印第一个字符。请更正此代码。
答案 0 :(得分:1)
如果要退出您所在的函数(包括它是main
函数),则只需执行return
:
if(str[i]==str[j])//compare
{
printf("%c",str[i]);
return 0;
}
如果您在循环后的代码中需要执行同一函数,则此方法将无效。您可以使用goto退出嵌套循环。打破嵌套循环是goto
的几种可接受用法之一:
for( i=0;i<strlen(str);i++)
{
for(j=i+1;j<strlen(str);j++)
{
if(str[i]==str[j])//compare
{
printf("%c",str[i]);
goto done;
}
}
}
done:
;
如果这是非嵌套循环,请使用break
答案 1 :(得分:1)
一个简单的解决方案是在找到第一个重复字符后立即返回:
#include <stdio.h>
int main()
{
int i,j;
char str[1000];
scanf("%s",str); // input the string
for (i = 0; str[i] != '\0'; i++)
{
for (j = i + 1; str[j] != '\0'; j++)
{
if (str[i] == str[j]) // compare
{
printf("%c", str[i]);
return 0;
}
}
}
}
答案 2 :(得分:1)
可以使用另一个数组对出现的字符进行计数。匹配是计数不再为零时。在abcdedcba
中,它将报告d
是第一个匹配的字符。
#include <stdio.h>
int main ( void) {
char all[256] = { 0};
char text[1000] = { 0};
int comp = 0;
if ( fgets ( text, sizeof text, stdin)) {
for ( comp = 0; text[comp]; ++comp) {
if ( all[(unsigned char)text[comp]]) {
printf ( "matched \'%c\'\n", text[comp]);
break;
}
all[(unsigned char)text[comp]]++;
}
}
else {
fprintf ( stderr, "fgets EOF\n");
}
if ( !text[comp]) {
printf ( "no matched characters\n");
}
return 0;
}
答案 3 :(得分:1)
以下是基于commented首先Eugene Sh.的提示的线性时间答案(不差于此):
#include <limits.h>
#include <stdio.h>
int main(void)
{
char str[1000];
char map[UCHAR_MAX + 1] = { 0 };
if (scanf("%999s", str) == 1)
{
for (int i = 0; str[i] != '\0'; i++)
{
int n = (unsigned char)str[i];
if (map[n]++ != 0)
{
printf("first duplicate: %c\n", str[i]);
break;
}
}
}
return 0;
}
这将记录map
数组中已经看到的每个字节的记录,并在找到重复的字符(不仅仅是字母)时中断循环。这有很多优点,包括:
strlen()
(如果优化程序没有检测到strlen()
只能被调用一次,这可能会使原始代码比O(N²)更复杂)它的主要缺点是,如果找不到重复项,它什么也不会说。如果那是不可接受的,则添加一个标志,该标志最初为false,在执行break
时设置为true,并在循环后进行测试。或者,代码可以使用break
代替return 0;
,在打印完重复项后退出程序,并可以打印“无重复项”消息并最终失败退出。
由于总搜索空间为255字节(因为不将空字节计为可重复字符),因此我们有理由认为,线性时间不是O(N),而是O(1)恒定时间。如果输入仅是小写的非字母,则如果输入中有27个字符,则必须重复。如果输入不是很受限制,那么在前256个字节中将有一个重复项(由于scanf()
和%s
在第一个空白处停止读取,因此该重复数要少一些,因此不能可以重复的任何空白字符)。 Big-O表示渐近运行时,并且27和256都不大,因此可以认为运行时为O(1)。