题目
对于给定的由可见字符和空格组成的字符串,按照下方的规则进行排序:
- 按照字母表中的顺序排序(不区分大小写);
- 同一字母的大小写同时存在时,按照输入顺序排列;
- 非字母字符保持原来的位置不参与排序;
直接输出排序后的字符串。字符串由 ASCII 码在 32 到 126 范围内的字符组成。
示例
示例1
输入:BabA
输出:aABb
示例2
输入:Hello NowCoder!
输出:CdeeH llNooorw!
分析
为了实现对给定字符串按照指定规则进行排序,可以采用以下思路:
- 遍历字符串,提取其中的字母并存储到一个新的容器中
- 对存储字母的容器进行排序,排序时不区分大小写
- 再次遍历原字符串,将排序后的字母依次放回原字符串中字母的位置,非字母字符保持不变
线性遍历+稳定排序
为了满足 “同一字母的大小写同时存在时,按照输入顺序排列” 这一规则,我们可以使用稳定排序算法来处理提取出的字母。std::stable_sort
可以保证相等元素的相对顺序不变。
时间复杂度:O(),其中
是字符串的长度,
是字符串中字母的数量
空间复杂度:O()
#include <bits/stdc++.h>
using namespace std;
// 自定义比较函数,不区分大小写进行比较
bool compare(char a, char b) {
return tolower(a) < tolower(b);
}
int main() {
string s;
// 读取输入的字符串
getline(cin, s);
vector<char> letters;
// 提取字符串中的字母
for (char c : s) {
if (isalpha(c)) {
letters.push_back(c);
}
}
// 使用稳定排序对字母进行排序,不区分大小写
stable_sort(letters.begin(), letters.end(), compare);
int letterIndex = 0;
string result;
// 构建排序后的字符串
for (char c : s) {
if (isalpha(c)) {
result += letters[letterIndex++];
} else {
result += c;
}
}
// 输出排序后的字符串
cout << result << endl;
return 0;
}
知识充电
tolower() 函数
tolower
函数是 C 和 C++ 标准库中的一个字符处理函数,用于将一个字符转换为小写形式。
C 中的 tolower
函数
#include <ctype.h>
int tolower(int c);
C++ 中的 tolower
函数
#include <cctype>
int tolower(int c);
tolower
函数仅对 ASCII 字符集中的大写字母有效,对于非 ASCII 字符或者非字母字符,它会直接返回原字符。由于返回值类型是 int
,在将结果赋值给 char
类型变量时,可能需要进行类型转换。对应的反函数是 toupper
函数。
isalpha() 函数
isalpha
函数是 C 和 C++ 标准库中的一个字符处理函数,主要用于判断一个字符是否为字母(包括大写字母和小写字母)。
C 中的 isalpha 函数
#include <ctype.h>
int isalpha(int c);
C++ 中的 isalpha 函数
#include <cctype>
int isalpha(int c);
参数 c
是一个 int
类型的值,不过在实际使用时通常传入一个 char
类型的值,函数会将其自动转换为 int
类型。isalpha
函数是基于 ASCII 字符集来判断字母的,如果 c
是字母,函数返回一个非零值;如果 c
不是字母,则返回 0。
getline() 函数
getline
函数在 C++ 中是一个常用的输入函数,主要用于从输入流中读取一行字符并存储到字符串对象中。
原型
#include <iostream>
#include <string>
std::istream& getline(std::istream& is, std::string& str, char delim);//delim(可选):指定行分隔符,默认为换行符 '\n'
std::istream& getline(std::istream& is, std::string& str);
举例
//std::getline(std::cin, line) 从标准输入读取一行内容,直到遇到换行符 '\n' 为止,并将读取的内容存储到 line 字符串中
#include <iostream>
#include <string>
int main() {
std::string line;
std::cout << "请输入一行文本:";
std::getline(std::cin, line);
std::cout << "你输入的文本是:" << line << std::endl;
return 0;
}
//指定了分隔符为逗号 ',',程序会从标准输入读取内容,直到遇到逗号为止,并将读取的内容存储到 input 字符串中
#include <iostream>
#include <string>
int main() {
std::string input;
std::cout << "请输入以逗号分隔的内容:";
std::getline(std::cin, input, ',');
std::cout << "读取到的内容是:" << input << std::endl;
return 0;
}