ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

华为OD字符串处理:单词排序与频率统计实战

华为OD字符串处理:单词排序与频率统计实战 1. 题目解析与需求拆解今天我们来拆解一道来自华为OD机考的字符串处理题目。这道题看似简单但实际考察了多种字符串操作和排序逻辑的综合运用能力。作为经历过多次机考的老手我发现这类题目往往在边界条件和排序规则上设置陷阱需要格外小心。题目要求我们对给定字符串进行两步处理对每个单词内部字符按字典序重新排列对所有单词按特定规则重新排序输入约束条件字符范围大小写字母、数字和空格字符串长度1-1000个字符输出要求单词间单空格分隔首尾无空格注意题目中的字典序指的是ASCII码顺序即数字大写字母小写字母。例如aB1排序后应为1Ba2. 核心算法设计与实现2.1 单词内部排序实现首先我们需要将字符串按空格分割成单词列表然后对每个单词进行内部字符排序。这里有几个技术要点def sort_word(word): # 将单词转为字符列表并排序 return .join(sorted(word))关键细节sorted()函数默认按ASCII码升序排列数字0-9的ASCII码是48-57大写字母A-Z是65-90小写字母a-z是97-1222.2 单词统计与排序规则这部分是本题的核心难点需要实现三级排序规则主排序按单词出现频率降序次级排序频率相同时按单词长度升序三级排序前两者都相同时按字典序升序from collections import defaultdict def process_string(s): # 分割字符串并处理每个单词 words [sort_word(w) for w in s.split()] # 统计词频 freq defaultdict(int) for w in words: freq[w] 1 # 实现三级排序 sorted_words sorted(words, keylambda w: (-freq[w], len(w), w)) # 去重并保持顺序 seen set() result [] for w in sorted_words: if w not in seen: result.extend([w] * freq[w]) seen.add(w) return .join(result)算法复杂度分析时间复杂度O(n*m log m) O(n log n)其中n是单词数m是平均单词长度空间复杂度O(n)用于存储词频和结果3. 边界条件与特殊测试用例在实际编码中我发现以下几个边界情况需要特别注意全相同单词如输入a a a输出应为a a a大小写敏感Ab和ab视为不同单词数字与字母混合a1排序后应为1a单字符单词如输入a b c b输出应为b b a c前导/后缀空格虽然题目说明用空格分隔但最好先strip()测试用例表输入预期输出说明hello worldehllo dlorw基础用例a A b B aa a A B b大小写敏感123 321 123123 123 123数字处理tree loves codingeert celov cdgino多单词场景4. 性能优化与实用技巧4.1 使用生成器减少内存占用对于大字符串可以改用生成器表达式words (sort_word(w) for w in s.strip().split())4.2 合并相同单词的排序观察到相同单词会被多次排序可以优化unique_words set(words) sorted_unique sorted(unique_words, keylambda w: (-freq[w], len(w), w))4.3 使用Counter替代defaultdictPython的collections.Counter更简洁from collections import Counter freq Counter(words)5. 完整实现与测试最终优化后的完整解决方案from collections import Counter def string_reorder(s): def sort_word(w): return .join(sorted(w)) words [sort_word(w) for w in s.strip().split()] freq Counter(words) # 获取去重单词并按规则排序 unique_words sorted(freq.keys(), keylambda w: (-freq[w], len(w), w)) # 重建结果列表 result [] for w in unique_words: result.extend([w] * freq[w]) return .join(result) # 测试用例 test_cases [ (hello world, ehllo dlorw), (a A b B a, a a A B b), (123 321 123, 123 123 123), (tree loves coding, eert celov cdgino), (a b c b, b b a c) ] for input_str, expected in test_cases: assert string_reorder(input_str) expected6. 常见问题与调试技巧Q1为什么我的排序结果不符合预期A检查三级排序规则的实现顺序是否正确先按频率降序再按长度升序最后按字典序升序Q2遇到内存不足错误怎么办A对于超长字符串使用生成器替代列表分批处理单词考虑使用更高效的数据结构如TrieQ3如何处理带标点的字符串A本题明确限定字符范围但实际开发中应先清洗数据import re clean_s re.sub(r[^a-zA-Z0-9 ], , s)调试技巧打印中间变量检查处理过程对每个排序阶段单独测试使用pdb设置断点调试7. 算法扩展与变种思考这道题目可以有多种变体考察不同的能力大小写不敏感版本words [sort_word(w.lower()) for w in s.split()]保留原始顺序的稳定排序 需要使用enumerate记录原始位置作为最后一级排序键多分隔符处理import re words [sort_word(w) for w in re.split(r[\s,;], s)]并行化处理 对于超长字符串可以用multiprocessing并行处理单词在实际面试中完成基础实现后可以主动讨论这些变体问题的解决方案展示思维广度。我建议平时练习时对每道题目都思考可能的变体这样在面试中就能从容应对考官的追问。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进