题目要求:
在一个字符串中找到第一个只出现一次的字符。如输入 abaccdeff,则输出 b。
第一种解法:遇到该题,我想最简单粗暴的方法便是,**依次拿每一个字符和其他所有字符比较,**如果有相同则说明该字符有重复,如果没有遇到相同的,则说明该字符就是第一个只出现一次,并且没有重复的字符。接下来,上代码!
char order1(char *s)
{
char *p = s;
//p作为外循环遍历,用来判断和内循环的内容是否相等
while(*p != '\0')
{
char *p1 = s ;//p1用来内循环遍历
int flag = 0;//标志位,如果存在内循环的值和外循环相等,则置1
//开始内循环遍历
while(*p1 != '\0')
{
//该if用来判断值相等
if(*p == *p1)
{
//该if从来剔除p和p1遍历到的是同一个地址
if(p == p1)
{
p1++;
continue;
}
//值相等flag置1,跳出循环
flag = 1;
printf("%c ",*p1);
break;
}
p1++;
}
if(flag == 0)
{
printf("没有重复的字符:%c\n",*p);
return *p;
}
p++;
}
return '\0';
}
上述方法可行,但是也存在一个弊端,通过分析,可以发现,其时间复杂度为O(n^2),当字符串很大是,计算量会增加不少,那么,就会思考,有没有什么方法可以降低时间复杂度呢?也还真有,那就是利用哈希表。哈希表是一个非常使用的数据结构,在这里只是简单版本的哈希表。
第二种解法:首先遍历一次字符串,求出每个字符在字符串中出现的次数,这个次数需保存在一个int型数组buf2中。这个buf2要开多大呢?一个无符号char类型,能表示数的范围为0 ~ 255,因此,要开辟的数组buf2的大小为256字节。一个字符,在计算机中是以二进制存储的,每一个字符对应的值都能用buf2数组的下表表示。在遍历过程中,每遍历到一个字符,则buf对应的下表所表示的元素就+1。这样一来,一此遍历就能统计出每一个字符出现的次数。再次,再从头开始遍历一次字符串,如果遇到对应下表值元素为1的即可。
接下来,上代码!
char order2(char *string)
{
if(string == NULL)
{
return '\0';
}
int size = 256;//一个字符占一个字节,能表示的二进制数范围 0 ~ 255
int *buf1 = malloc (size);//定义一个动态数组,大小为size
//初始化动态数组,初始值为0
for(int i = 0;i < size; i++)
{
buf1[i] = 0;
}
//第一遍遍历字符串,奖每个字符对应的二进制值作为buf1的下标,得到每个字符出现的次数
char *buf2 = string;
while(*buf2 !='\0')
{
buf1[*buf2++]++;
}
//第二遍遍历字符串,求出第一个只出现一次的字符,每次都是按照字符串的顺序遍历
buf2 = string;
while(*buf2 != '\0')
{
if(buf1[*buf2] == 1)
{
printf("没有重复的字符:%c\n",*buf2);
return *buf2;
}
buf2++;
}
return '\0';
}