三类题目
1.输入一个字符串,按照字符的个数进行排序,如果个数相同按照字符顺序输出。
示例 1:
输入:bbaaacddtf
输出:ctfbda
示例 2:
输入:acddtadtabdc
输出:bctad
思考:
首先使每一个字符都-‘a’变为数字后存储在一个新数组c中,那么相同的则会在这个新数组的同一位置出现,自加后即可得到对应的出现次数。比如aaaaccd 那么对应的就是a[0]=4,a[2]=2,a[3]=1最多也仅有26个,以这26个为循环进行,每次寻找出非0且最小的那个,这就是第一层循环,第二层循环也就是从最小的开始一个一个进行比较(需要自己再写一个找出最小数的函数),如果找到与最小的数相等的值,那么则把这个对应的的循环次数的值+’a’变为字符然后赋值给新的一个新的字符数组,同时把这个次数值变为0,保证下一次它就不是最小的,最后输出结果即可。
源代码:
#include<stdio.h>
#include<string.h>
int fn(int s[27]){
int min = 100;
for(int j = 0; j <26; j++){
if(s[j] < min && s[j] != 0)
min = s[j];
}
return min;
}
main(){
char a[99];
char e[99];
int c[99]={
0};
int i, j, n, k=0, m, z=0;
char b, fu, min;
gets(a);
n = strlen(a);
for(i = 0; i < n; i++)
c[a[i]-'a']++;
for(i = 0; i < 26; i++){
min = fn(c);
for(j = 0; j<26; j++){
if(c[j] == min){
e[k++] = j + 'a';
c[j] = 0;
}
}
}
puts(e);
}
2.第二个字符串不变,每个是多少次就输出多少次,在中间加入一个while循环即可,同样要注意在结尾加入 b[i] = ‘\0’;是字符串结束。(在第一个的基础上进行修改)
for( i = 0 ; i < 26; i++){
min = fn(c);
for( j = 0; j < 26; j++){
if(c[j] == min){
while(c[j] != 0){
e[k++]=j+'a';
c[j]--;
}
}
}
}
e[k]='\0';
puts(e);
3.如果出现次数相同,不按字典序排,按输入顺序排序:
思考:
不按字典序进行排列,也就是不能用数字加’a’的方法进行储存,自己考虑了好几天,没想出来,问同学后经过多次调试,使用结构体进行统计与排序,解决了这个问题。
主要核心思想通过结构体将两个数据捆绑到一起,剩下和前面一样,在比较min时不能忘记0的情况的出现。
#include<stdio.h>
#include<string.h>
struct a{
char ch;
int number=0;
}s[27];
int fn(a s[27])
{
int min = 100;
for(int j = 0; j < 26; j++)
{
if(s[j].number < min && s[j].number!=0)
min = s[j].number;
}
return min;
}
main()
{
char a[99];
char e[99];
int c[99]={
0};
int i,j,n,k=0,z=0;
char b,fu,min;
gets(a);
n=strlen(a);
for(i = 0; i<n; i++){
s[i].ch = a[i];
}
for(i = 0;a[i]!='\0'; i++){
for(j = 0; j <= i; j++){
if(a[i]==s[j].ch){
s[j].number++;
break; //使用break保证全部数据都存到出现的第一个number中 第一个不断加来记录总数。
}
}
}
for(i=0;i<n;i++)
{
min = fn(s);
for(j=0;j<n;j++)
{
if(s[j].number==min)
{
e[k++]=s[j].ch;
s[j].number=0;
}
}
}
puts(e);
}
总结:第三个问题写了很久没有思绪,在同学的帮助下实现了代码,还要多练习,通过结构体进行排序的这个方法也要多练习。