#P3006. 字符串重新排序(100分)
-
1000ms
Tried: 236
Accepted: 75
Difficulty: 5
所属公司 :
华为od
-
算法标签>排序算法
字符串重新排序(100分)
题面描述
给定一个字符串 s,s 包括以空格分隔的若干个单词。请对 s 进行如下处理后输出:
-
单词内部调整:对于每个单词,如果该单词中不包含大写字母,则将单词中的字母按字典序重新排序;否则,保持单词不变。
-
单词间顺序调整:
- 统计每个单词出现的次数,并按次数降序排列。
- 如果次数相同,按单词长度升序排列。
- 如果次数和单词长度均相同,按字典升序排列。
最后,输出处理后的字符串,每个单词以一个空格分隔。
思路
模拟题,按照题面意思模拟
-
分词处理:首先,将输入字符串按照空格分割成若干个单词。
-
单词内部调整:
- 对于每个单词,检查是否包含大写字母。
- 如果不包含大写字母,则将单词中的字符按字典序排序。
- 否则,保持单词不变。
-
统计频率:统计每个处理后的单词出现的次数。
-
排序规则:
- 首先按照单词出现的频率进行降序排序。
- 如果频率相同,则按单词长度进行升序排序。
- 如果频率和长度都相同,则按字典序进行升序排序。
-
输出结果:按照排序后的顺序,将单词重复其出现的次数,拼接成最终的输出字符串,每个单词之间用空格分隔。
cpp
#include <bits/stdc++.h>
using namespace std;
int main(){
string s;
// 读取整行输入
getline(cin, s);
// 分割单词
vector<string> words;
string word;
stringstream ss(s);
while(ss >> word){
// 检查是否有大写字母
bool hasUpper = false;
for(char c: word){
if(isupper(c)){
hasUpper = true;
break;
}
}
if(!hasUpper){
// 如果没有大写字母,排序字母
sort(word.begin(), word.end());
}
// 添加到单词列表
words.push_back(word);
}
// 统计频率
unordered_map<string, int> freq;
for(auto &w: words){
freq[w]++;
}
// 提取唯一单词
vector<string> uniqueWords;
for(auto &p: freq){
uniqueWords.push_back(p.first);
}
// 自定义排序规则
sort(uniqueWords.begin(), uniqueWords.end(), [&](const string &a, const string &b) -> bool{
if(freq[a] != freq[b]){
return freq[a] > freq[b]; // 频率降序
}
if(a.size() != b.size()){
return a.size() < b.size(); // 长度升序
}
return a < b; // 字典序升序
});
// 构建输出
string result = "";
for(auto &w: uniqueWords){
for(int i=0; i<freq[w]; ++i){
result += w + " ";
}
}
// 去掉最后一个空格
if(!result.empty()){
result.pop_back();
}
// 输出结果
cout << result;
}
python
from collections import defaultdict
def main():
s = input().strip()
words = s.split()
processed = []
freq = defaultdict(int)
for word in words:
# 检查是否有大写字母
has_upper = any(c.isupper() for c in word)
if not has_upper:
# 如果没有大写字母,排序字母
sorted_word = ''.join(sorted(word))
processed.append(sorted_word)
else:
# 否则保持不变
processed.append(word)
# 统计频率
freq[processed[-1]] += 1
# 获取唯一单词
unique_words = list(freq.keys())
# 自定义排序
unique_words.sort(key=lambda x: (-freq[x], len(x), x))
# 构建输出
result = []
for word in unique_words:
result.extend([word] * freq[word])
print(' '.join(result))
if __name__ == "__main__":
main()
java
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
String[] words = s.split("\\s+");
List<String> processed = new ArrayList<>();
Map<String, Integer> freq = new HashMap<>();
for(String word: words){
boolean hasUpper = false;
for(char c: word.toCharArray()){
if(Character.isUpperCase(c)){
hasUpper = true;
break;
}
}
if(!hasUpper){
// 如果没有大写字母,排序字母
char[] chars = word.toCharArray();
Arrays.sort(chars);
word = new String(chars);
}
processed.add(word);
freq.put(word, freq.getOrDefault(word, 0) + 1);
}
// 获取唯一单词
List<String> uniqueWords = new ArrayList<>(freq.keySet());
// 自定义排序
Collections.sort(uniqueWords, new Comparator<String>(){
public int compare(String a, String b){
if(!freq.get(a).equals(freq.get(b))){
return freq.get(b) - freq.get(a); // 频率降序
}
if(a.length() != b.length()){
return a.length() - b.length(); // 长度升序
}
return a.compareTo(b); // 字典序升序
}
});
// 构建输出
StringBuilder sb = new StringBuilder();
for(String word: uniqueWords){
for(int i=0; i<freq.get(word); i++){
sb.append(word).append(" ");
}
}
// 去掉最后一个空格
if(sb.length() > 0){
sb.setLength(sb.length()-1);
}
// 输出结果
System.out.println(sb.toString());
}
}
题目内容
给定一个字符串 s ,s 包括以空格分隔的若干个单词,请对 s 进行如下处理后输出:
1、单词内部调整:对每个单词字母重新按字典序排序
2、单词间顺序调整:
1)统计每个单词出现的次数,并按次数降序排列
2)次数相同,按单词长度升序排列
3)次数和单词长度均相同,按字典升序排列
请输出处理后的字符串,每个单词以一个空格分隔。
输入描述
一行字符串,每个字符取值范围:[a−z,A−Z] 以及空格,字符串长度范围:[1,1000]
输出描述
输出处理后的字符串,每个单词以一个空格分隔。
样例1
输入
This is an apple
输出
an is This aelpp
样例2
输入
My sister is in the house not in the yard
输出
in in eht eht My is not adry ehosu eirsst