从字符串切片匹配俄语单词时出现无限输出短单词的问题排查
俄语字符串切片匹配单词问题修复
问题描述
有一段字符串示例:'АРВТРВТПЛЯЖАОВР',其中隐藏着单词'ПЛЯЖ'。使用包含约150万个俄语所有变格形式单词的列表文件,遍历该字符串的所有可能切片并与列表中的单词匹配,期望输出所有匹配结果。但运行代码后,仅持续输出长度不超过3个字符的单词,无法找到更长的目标单词,疑似文件读取或循环逻辑存在问题,但无法定位具体原因。
原代码
rus_words = open('russian.txt') #opening a file in read mode text = 'АРВТРВТПЛЯЖАОВР' #Initial line length_of_text = len(text)+1 #Text length for line in rus_words: #Iterating through the values in the file for i in range(length_of_text): #Iterating through the row indexes for j in range(1,11): #Iterating over the possible length of a word #(Here I assume that the word is no more than 10 characters) maybe_word = text.lower()[i:i+j] #Formation of a possible word if maybe_word in line: #Comparison of the received word with the values in the list print(maybe_word) #Output of matches
问题根源
- 循环逻辑倒置:当前代码先遍历单词库的每一行,再遍历字符串的所有切片,检查切片是否为当前行单词的子串。这会导致短切片只要是某个长单词的一部分就被反复输出,而长单词本身的完整切片匹配场景极少触发,自然无法被输出。
- 未处理文件换行符:单词库每行末尾带有换行符
\n,即使切片与单词内容一致,也会因换行符的存在增加匹配难度,且冗余字符会干扰判断。 - 冗余计算严重:每次遍历单词库行都重复生成所有字符串切片,极大浪费系统资源,降低运行效率。
修复后的代码
# 将单词库加载至集合,利用集合O(1)的查询效率提升性能 with open('russian.txt', 'r', encoding='utf-8') as f: # 去除每行换行符并统一转小写,存入集合去重 rus_words_set = {line.strip().lower() for line in f} target_text = 'АРВТРВТПЛЯЖАОВР'.lower() text_length = len(target_text) matched_words = set() # 用集合存储匹配结果,自动去重 # 生成所有可能的字符串切片,再查询是否存在于单词集合中 for start_idx in range(text_length): # 生成从start_idx开始,长度1到10的切片,避免超出字符串边界 for word_length in range(1, 11): end_idx = start_idx + word_length if end_idx > text_length: break current_slice = target_text[start_idx:end_idx] if current_slice in rus_words_set: matched_words.add(current_slice) # 按单词长度从长到短输出结果,便于查看目标长单词 for word in sorted(matched_words, key=lambda x: len(x), reverse=True): print(word)
修复说明
- 调整循环顺序:先生成所有可能的字符串切片,再到单词集合中查询匹配,直接命中所有存在的单词,包括目标长单词
пляж。 - 使用集合存储单词:集合的成员查询速度远优于列表,150万条数据也能快速检索,同时自动去除单词库中的重复条目。
- 统一格式处理:读取单词时去除换行符,将所有内容转小写,确保与字符串切片的格式一致,避免大小写或冗余字符导致的匹配失败。
- 去重输出:用集合存储匹配结果,避免同一单词因出现在多个切片位置而被重复输出,同时按长度排序后输出更直观。
内容的提问来源于stack exchange,提问作者SasambaDio
相关产品推荐
相关产品推荐

