C++题解(34) 2025年顺德区中小学生程序设计展示活动(初中组C++)U560289 字符串排序(一)和 U560136 字符串排(二)题解
注:原题表述有误,出题者已更正。
U560289 字符串排序(一)
题目描述
输入一个字符串,长度小于等于200个字符,然后将输入的字符串按字符升序排序后输出。注意以下规则:
①26个字母按a→z顺序排序;
②一组字符串内可能有空格,直接丢弃处理;
③保证字符串只含小写字母和空格。
输入格式
第1行有1个整数n,代表着n组输入数据。
第2到n+1行,均有一组字符串。
输出格式
输出n行,每行为处理后的字符串。
输入输出样例
输入 #1
1 tian qin输出 #1
aiinnqt说明/提示
样例解析
字符串升序排序后应为aiinnqt。
数据范围
n≤1000,输入数据每行只有一个长度不大于200的字符串,且仅含大小写字母和空格。
参考答案
#include <iostream> #include <string.h> #include <stdio.h> using namespace std; int n,a[140]; string s; void Sort()//使用桶排序排序字符串s {for(int i=0;i<s.size();i++){a[s[i]]++;} } void Print()//输出排序完后的结果 {for(int i=90;i<=130;i++){for(int j=1;j<=a[i];j++){printf("%c",i);}}cout<<endl; } int main() {cin>>n;getline(cin,s);for(int i=1;i<=n;i++){memset(a,0,sizeof(a));//桶排序数组a赋值为零getline(cin,s);Sort();Print();}return 0; }
解题思路
本题最难的部分在于给字符串排序。本题使用桶排序最为方便简单。
算法概述:
桶排序算法原理是将数组分到有限数量的桶里,再对每个桶分别排好序,最后一次将每个桶中排好序的数输出。
解题步骤:
1.用 cin 或 scanf 读入字符串行数n,再用 getline函数 读取每行的字符串。
注意:getline函数可以读取一整行的字符(包括空格)。若 cin 或者 scanf 与getline函数连用,需要多读取一次(
getline函数
会读取直到遇到换行符,并丢弃换行符,cin
会留下换行符在缓冲区,两者连用可能会导致输入错误)。2.用桶排序给字符串排序。
本文中的参考代码中考虑空间足够,索性直接开了一个140个元素的整型数组a用来存储a下标对应ASCII码字符在字符串中出现的个数。(空格的ASCII码为32)。
3.用for循环遍历数组a,输出a的下标所对应ASCII码代表的字符,并输出对应个字符。
4.每次循环开始用 memset函数把数组a赋值为0。
U560136 字符串排(二)
题目背景
【题干与《字符串排序(一)》基本一致,仅规则②③和样例有所不同】
题目描述
输入一个字符串,长度小于等于200个字符,然后将输入的字符串按字符升序排序后输出。注意以下规则:
①26个字母按a→z顺序排序;
②可能会有大写字母,其顺序比对应小写字母靠后,如a→A→b→B→...→z→Z。
③一组字符串内可能有空格,需要替换为'&',并在原位置输出
输入格式
第1行有1个整数n,代表着n组输入数据。
第2到n+1行,均有一组字符串。
输出格式
输出n行,每行为处理后的字符串。
输入输出样例
输入 #1
1 TiAn qiN输出 #1
Aiin&NqT说明/提示
样例解析
字符串升序排序后应为AiinNqT,原第五个字符位有空格,因此答案为Aiin&NqT。
数据范围
n≤1000,输入数据每行只有一个长度不大于200的字符串,且仅含大小写字母和空格。
参考答案
#include <bits/stdc++.h> using namespace std;bool cmp(char a,char b) {if(tolower(a)!=tolower(b)){return tolower(a)<tolower(b); //先按字母表顺序排序(不区分大小写)}return a>b; //同一字母:小写字母排在大写字母前面 }int main() {int n;cin>>n;cin.ignore(); //忽略换行符while(n--){string s;getline(cin,s); //读入整行字符串(包含空格)string t(s.size(),' '); //创建与s等长的字符串,初始为空格for(int i=0;i<s.size();i++){if(s[i]==' ')t[i]='&'; //空格位置替换为&}sort(s.begin(),s.end(),cmp); //按自定义规则排序int i=0;//跳过排序后开头的空格(排序后空格集中在前面)while(i<s.size()&&s[i]==' ')i++;for(int j=0;j<t.size();j++){if(t[j]=='&')continue; //跳过标记的&位置t[j]=s[i++]; //非空格位置填入排序后的字符}cout<<t<<endl; //输出结果}return 0; }
解题思路 (代码解析)
解题步骤:
1.读入字符串数量
cin.ignore()作用:
cin >> n
读取整数后,输入缓冲区会残留一个换行符'\n'
若不忽略,后续的getline()
会立即读到空行
cin.ignore()
默认忽略1个字符(正好是残留的换行符)2.空格处理
getline()
读取整行(包括空格)创建临时字符串
t
,在原始空格位置标记'&'其他位置暂时保留空格(后续会被覆盖)
3.调用自定义比较函数
当字母不同时(忽略大小写),按字母表升序排序
当是同一字母时(如'a'和'A'):
小写字母(ASCII码值大)排在大写字母前面(ASCII码值小)
实现题目要求的排序规则:a→A→b→B→...→z→Z
4.排序与空格跳过
空格在ASCII表中(输入数据的数据中)值最小,排序后会集中在字符串开头
循环跳过所有空格,
i
指向第一个非空格字符5.结果组装输出
遍历临时字符串
t
:
遇到'&':保持原样(对应原始空格位置)
其他位置:依次填入排序后的非空格字符
最终得到:原空格位置显示'&',其他位置显示排序后的字符
创作历时1.5小时,感谢阅读!