题目描述
给定一个字符串s,s包括以空格分隔的若干个单词,请对s进行如下处理后输出:
1、单词内部调整:对每个单词字母重新按字典序排序
2、单词间顺序调整:
1)统计每个单词出现的次数,并按次数降序排列
2)次数相同,按单词长度升序排列
3)次数和单词长度均相同,按字典升序排列
请输出处理后的字符串,每个单词以一个空格分隔。
输入描述
一行字符串,每个字符取值范围:[a-zA-z0-9]以及空格,字符串长度范围:[1,1000]
输出描述
输出处理后的字符串,每个单词以一个空格分隔。
用例
输入 | This is an apple |
输出 | an is This aelpp |
说明 | 无 |
输入 | My sister is in the house not in the yard |
输出 | in in eht eht My is not adry ehosu eirsst |
说明 | 无 |
单词处理与排序算法详解
核心解题思路
本题需要对字符串中的单词进行双重处理:单词内部字符排序和单词间多重排序。解题关键在于:
- 单词内部处理:对每个单词的字符重新按字典序排序
- 单词间排序:按照三重规则排序
- 规则1:按单词出现频率降序排列
- 规则2:频率相同则按单词长度升序排列
- 规则3:长度相同则按字典序升序排列
处理流程
- 分割字符串:将输入字符串按空格分割成单词列表
- 单词内部排序:对每个单词的字符进行字典序排序
- 统计频率:计算每个处理后的单词出现次数
- 多重排序:按照三重规则对单词列表排序
- 结果拼接:将排序后的单词用空格连接
完整代码实现
def process_string(s):# 1. 分割字符串为单词列表words = s.split()# 2. 对每个单词内部字符排序sorted_words = []for word in words:# 将单词转为字符列表排序后重新组合sorted_word = ''.join(sorted(word))sorted_words.append(sorted_word)# 3. 统计处理后的单词频率from collections import Counterword_freq = Counter(sorted_words)# 4. 多重排序:频率降序 > 长度升序 > 字典序升序# 使用元组作为排序键:(-频率, 长度, 单词)sorted_list = sorted(sorted_words,key=lambda word: (-word_freq[word], len(word), word))# 5. 拼接最终结果return ' '.join(sorted_list)# 主程序
if __name__ == "__main__":input_str = input().strip()output = process_string(input_str)print(output)
算法原理解析
1. 单词内部排序
sorted_word = ''.join(sorted(word))
sorted(word)
:将单词拆分为字符列表并按ASCII值排序''.join()
:将排序后的字符重新组合为字符串- 示例:
- “apple” → [‘a’,‘p’,‘p’,‘l’,‘e’] → 排序为[‘a’,‘e’,‘l’,‘p’,‘p’] → “aelpp”
- “This” → [‘T’,‘h’,‘i’,‘s’] → 排序为[‘T’,‘h’,‘i’,‘s’] → “This” (已有序)
2. 频率统计
from collections import Counter
word_freq = Counter(sorted_words)
Counter
类高效统计单词出现次数- 返回字典:{单词: 出现次数}
- 示例:对于输入[“in”, “eht”, “in”] → 频率统计为{‘in’:2, ‘eht’:1}
3. 多重排序
key=lambda word: (-word_freq[word], len(word), word)
- 第一关键字:
-word_freq[word]
- 负号实现降序效果(频率越高,负值越小)
- 示例:频率2变为-2,频率1变为-1,-2 < -1 → 频率2排在前面
- 第二关键字:
len(word)
- 按单词长度升序排列
- 长度短的单词排在前面
- 第三关键字:
word
- 按字典序升序排列
- 字典序小的单词排在前面(按字符ASCII值比较)
示例解析
示例1:输入"This is an apple"
-
单词内部排序:
- “This” → “This”(字符已有序)
- “is” → “is”
- “an” → “an”
- “apple” → “aelpp”
-
频率统计:
- 所有单词出现1次
-
多重排序:
- 频率相同 → 比较长度
- 长度:“an”(2)、“is”(2) < “This”(4) < “aelpp”(5)
- "an"和"is"长度相同 → 比较字典序:“an” < “is”(‘a’(97) < ‘i’(105))
-
最终排序:
- [“an”, “is”, “This”, “aelpp”]
- 输出:“an is This aelpp”
示例2:输入"My sister is in the house not in the yard"
-
单词内部排序:
- “My” → “My”
- “sister” → “eirsst”
- “is” → “is”
- “in” → “in”(两次)
- “the” → “eht”(两次)
- “house” → “ehosu”
- “not” → “not”
- “yard” → “adry”
-
频率统计:
- “in”:2, “eht”:2, 其他单词:1
-
多重排序:
- 频率降序:"in"和"eht"优先(频率2 > 1)
- 长度升序:
- “in”(2) < “eht”(3)(长度短的在前)
- 其他单词:(“My”:2, “is”:2) < “not”:3 < “adry”:4 < “ehosu”:5 < “eirsst”:6
- 字典序升序:
- "in"和"eht"内部相同
- “My” < “is”(‘M’(77) < ‘i’(105))
-
最终排序:
- [“in”,“in”,“eht”,“eht”,“My”,“is”,“not”,“adry”,“ehosu”,“eirsst”]
- 输出:“in in eht eht My is not adry ehosu eirsst”
总结
实际应用
- 文本分析:词频统计与排序
- 数据清洗:统一单词格式
- 搜索引擎:搜索结果排序
- 自然语言处理:词汇规范化
- 日志分析:高频事件识别
通过这个解法,初学者可以掌握:
- 字符串操作的核心技巧
- 多重排序的实现方法
- 频率统计的高效方式
- 复杂问题的分解思路
- Python内置函数的灵活应用
这种"分治+排序"的方法是处理字符串排序问题的通用模式,理解后可以扩展到更复杂的文本处理场景中。