题目笔记1:第一个只出现一次的字符(两种解法C语言实现)

题目要求

在一个字符串中找到第一个只出现一次的字符。如输入 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';
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值