N-44. 字符串的可视化
题目描述
在实际生活中,我们对于乱序的数据感到迷惑,并且很难把握住数据的价值,所以我们使用各种各样的手段来进行数据分析,在数据分析之后,数据的可视化也同样重要,优秀的可视化成果往往会放大数据的隐藏价值,进而影响我们的生活。
现在请聪明的你运用排序的分析方法对我们给出的字符串进行处理,并对其结果进行可视化,在这里我们选定绘制类似柱状图的方法进行可视化。
输入格式
一行一个字符串,只包含有大小写字母。
输出格式
输出应该有数行,51列。第2i-1列应该属于字符串里个数第i多的字母,若两个字母个数一样,字典序小的应该在前面。该列最后一行应该是这个字母的大写,然后从最后一行开始向上打印总共k个’#’号(k为该字母在字符串中的个数),每行一个。若已经打印了k个’#’,打印一个空格。第2i列应该是一个空格。输出应保证输出的字母在同一行,且无空行。
样例输入
WoJueDeBianChengZhenDeShiTaiYouQueLa
样例输出
#
#
#
# # # # # #
# # # # # # # #
# # # # # # # # # # # # # # # # # # #
E A H I N U D O B C G J L Q S T W Y Z F K M P R V X
数据范围
字符串长度不超过10000.





这道题要理解51列是26*2-1,最后一行意味着输出26个字母和25个空格。
所以主要任务是:
1.将字符串全换为大写,因为大小写有区别
2.将字符串去除重复的部分并且记录重复次数
3.将字符串按重复次数大小排序,并且大小相同的按字母序排序
4.由输入字符串不一定含26个字母,因此,最后要将未出现的字母排序
5.打印。按行打印,满足打印#,不满足打印空格
#include <stdio.h> #include <stdlib.h> #include<string.h> //按数量排序再打印各自的列 //数量排序是不是可以有重复的就直接后一位进一 //先不排序,算各自有几个存在b里,然后在换a的时候把b也换了 //无语了,最终要输出26个字母,难怪是51列,难怪有字母没有打印#,并且输出全是大写 int main() { char a[10000]={0}; scanf("%s",a); int b[10000]={1};//是不是它并没有全部赋值为1? int cnt = strlen(a); int ans = 0; int ans1 = 0; //删不动了,还是新开一个数组放吧 //得先全换成大写,,呃,还以为会有什么公式,, 好像存的就是ascii,所以不用'a[i]' for(int i = 0 ;a[i]!='\0';i++){ if('a'<=a[i]&&a[i]<='z'){//不能直接就像列数学表达式,要&& a[i]=a[i]-32;//oo是可以的,这里存的是字符型的,不是数组 } } //如果不在这里全换成大写,A和a就是不一样的数 for(int i = 0;a[i]!='\0';i++)//是不是可以用!='\0' { b[i]=1;//这样才是真正的初始化 for(int j = i+1; a[j] != '\0';j++) { if(a[i]==a[j]){ b[i]++; ans++; for(int k = j;k<cnt-ans+1;k++){ a[k]=a[k+1]; a[cnt-ans+1]='\0';//最后一位就是应该是这个cnt-ans,但是要把之后的去掉,应该加一位,不然会把没有比较的去掉了 }//但是这样它不会判删去一位后不会继续把a[i]和a[i+1]比较。所以得每次删了一位后还要继续判本位 j--; //直接这样,下次继续判 } } //printf("%d\n",b[i]); } //printf("%s\n",a);//这里新开了一个字符串存放,,单纯不相等就放还是会错!所以不行,cao 终于好了 int cnt1 =strlen(a); //printf("%d\n",ans); for(int i = 0;a[i] !='\0';i++) { for(int j = i+1;a[j]!='\0';j++){ if(b[i]<b[j]){ int temp1 = a[j]; a[j]=a[i]; a[i]=temp1; int temp2 = b[j]; b[j]=b[i]; b[i]=temp2; } if(b[i]==b[j]){ if(a[i]>a[j])//可以这么比较吗、、 kyky {int temp1 = a[j]; a[j]=a[i]; a[i]=temp1; int temp2 = b[j]; b[j]=b[i]; b[i]=temp2; }} } }//全部排好了,只差打印了 //printf("%s\n",a); //无语了,最终要输出26个字母,难怪是51列,难怪有字母没有打印#,并且输出全是大写 //把字母从小到大去比较,没有就加在末尾 其实相当于除去输入过的字母 char str[100000];//记得要设 strcpy(str, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");//就想直接对它加上了,,不知道末尾会不会自动加上'\0'也就是不知道sizeof之后是27还是26 int cnt2 = 0; int cnt3 = 0; char s[10000]; for(int i = 0;str[i]!='0';i++){ cnt2 = 0;//如果它没有出现的次数是a[i]的长度就行 for(int j = 0;a[j]!='\0';j++) { if(str[i]!=a[j]) cnt2++; } if(cnt2==cnt1)//a[cnt1+i]=str[i];//这样失败了,好像不能直接加,开个新的把,到时候直接复制 { s[cnt3]=str[i]; cnt3++; } } strcat(a,s);//把s加到a后面 //printf("%s\n",a); //一行一个循环,每行再判是否大于这个数,若小于就打印空格 for(int i = 0 ; i<b[0];i++){ for(int j = 0;a[j]!='\0';j++){ //好像这个判错了 if(b[j]>=b[0]-i){ if(j==25)printf("#"); else printf("# ");} else {if(j==25)printf(" "); else printf(" "); }//都得判,最后一个不一样 } printf("\n"); } for(int i = 0;a[i]!='\0';i++){ //因为只有51列,最后一个要特判 if(i==25) printf("%c",a[i]); else printf("%c ",a[i]); } printf("\n"); return 0; } //草!终于几把的靠自己全a了,真的高兴得想死
浙公网安备 33010602011771号