【C语言】字符个数统计

题目描述

题目来源字符个数统计_牛客题霸_牛客网 (nowcoder.com)

编写一个函数,计算字符串中含有的不同字符的个数。字符在 ASCII 码范围内( 0~127 ,包括 0 和 127 ),换行表示结束符,不算在字符里。不在范围内的不作统计。多个相同的字符只计算一次

例如,对于字符串 abaca 而言,有 a、b、c 三种不同的字符,因此输出 3 。

数据范围:1 ≤ n ≤ 500

输入描述:

输入一行没有空格的字符串。

输出描述:

输出 输入字符串 中范围在(0~127,包括0和127)字符的种数。

示例1

输入:

abc

输出:

3

示例2

输入:

aaa

输出:

1

思路解析

这题与其说是字符个数统计,不如说是字符种类统计,就好比我给你一串数组,要你找出里面有几个数字出现了一次一样

那么解决方案其实也不止一个:

  1. 创建一个新的字符数组用于存放已出现的字符,并遍历原字符串,找到一个新的就存一个数组里
  2. 对字符串进行排序后遍历数组,遇到一个新的直接计数器+1即可

但是很明显第二个更为简单,所以我们用第二个思路


首先创建数组并收集字符,老套路不再多说

int main(){
    char str[501];
    gets(str);
    return 0;
}

然后就是要解决我们的排序问题,这里可以自己写一个排序的算法,但是这里我更加推荐直接使用qsort函数省事省心,那么先让我们回顾一下qsort函数


void qsort (void* base, size_t num, size_t size,int (*compar)(const void*,const void*));

返回值:无返回值,只会对base指向的位置进行排序

参数:base,指向我们要排序的数据的起始点

num,我们要排序的数据的个数

size,我们要排序的单个数据的大小

compar,一个函数指针,指向一个比较大小函数,用于告诉qsort如何比较你提供的数据的大小,其中该函数的参数为两个const void*,返回值为int

假设有下列campar声明

int compar (const void* p1, const void* p2);

当返回值< 0p1指向的元素会被放在p2指向的元素前面

当返回值= 0p1p2位置不变

当返回值> 0p1指向的元素会被放在p2指向的元素后面

实际上这个返回值就是会影响你的排序结果为正序或逆序,假如不符合预期就交换一下位置就行


那么在这里我们想要用qsort函数,就要知道我们这个字符串存了多少个有效字符,所以我们就写出一个简单循环来进行统计

    int count = 0;
    while (str[count]) {
        count++;
    }

然后就是写一个比较大小的函数,由于字符的本质是整型,所以实际上我们直接返回两个字符的差值即可

但是这里有几个注意点:

  1. void*类型指针要先进行类型转换才能用
  2. 这里不要被返回值迷惑,将指针类型转成了int*,否则解引用就变成访问4个字节了
  3. 参数的类型和返回值的类型一定对应,包括const
int cmp_char (const void* p1, const void* p2) {
    return *(char*)p1 - *(char*)p2;
}

那么我们就可以调用qsort来进行排序了

qsort(str, count, 1, cmp_char);

最后,就是统计字符出现的种类数了,我们就从第一个开始,和后面的一个字符进行比较就行,如果发现不相等,就让我们的计数器自增

这里有几个注意点:

  1. 循环应该执行count-1
  2. 计数器的起始数应该为1,因为刚开始一定会有一个种类的字符,并且我们的比较算法是不会加上第一个类型的字符的。从循环次数的角度考虑,当只有一个字符的时候,循环执行count-1次,也就是0次,但是实际上也有一个字符

代码如下

    int num = 1;
    for (int i = 0; i < count - 1; i++) {
        if (str[i] != str[i + 1]) {
            num++;
        }
    }

那么最后打印我们的num即可

代码总览

#include <stdio.h>
#include <stdlib.h>

int cmp_char (const void* p1, const void* p2) {
    return *(char*)p1 - *(char*)p2;
}
int main() {
    char str[501];
    gets(str);
    int count = 0;
    while (str[count]) {
        count++;
    }
    qsort(str, count, 1, cmp_char);
    int num = 1;
    for (int i = 0; i < count - 1; i++) {
        if (str[i] != str[i + 1]) {
            num++;
        }
    }
    printf("%d", num);
    return 0;
}
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值