题目描述
题目来源:字符个数统计_牛客题霸_牛客网 (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即可
但是很明显第二个更为简单,所以我们用第二个思路
首先创建数组并收集字符,老套路不再多说
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);
当返回值< 0
:p1
指向的元素会被放在p2
指向的元素前面
当返回值= 0
:p1
和p2
位置不变
当返回值> 0
:p1
指向的元素会被放在p2
指向的元素后面
实际上这个返回值就是会影响你的排序结果为正序或逆序,假如不符合预期就交换一下位置就行
那么在这里我们想要用qsort
函数,就要知道我们这个字符串存了多少个有效字符,所以我们就写出一个简单循环来进行统计
int count = 0;
while (str[count]) {
count++;
}
然后就是写一个比较大小的函数,由于字符的本质是整型,所以实际上我们直接返回两个字符的差值即可
但是这里有几个注意点:
void*
类型指针要先进行类型转换才能用- 这里不要被返回值迷惑,将指针类型转成了
int*
,否则解引用就变成访问4个字节了 - 参数的类型和返回值的类型一定对应,包括
const
int cmp_char (const void* p1, const void* p2) {
return *(char*)p1 - *(char*)p2;
}
那么我们就可以调用qsort
来进行排序了
qsort(str, count, 1, cmp_char);
最后,就是统计字符出现的种类数了,我们就从第一个开始,和后面的一个字符进行比较就行,如果发现不相等,就让我们的计数器自增
这里有几个注意点:
- 循环应该执行
count-1
次 - 计数器的起始数应该为
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;
}