为何字典键对应值的len()结果不符合预期?wordPattern函数问题排查
理解你的wordPattern函数错误:len()的误解与双射逻辑问题
嘿,我来帮你理清楚这个问题!首先,你遇到的第一个困惑——为什么len(new_dict[key])返回3而不是1——是因为你误解了len()函数在这里的作用:
你以为len(new_dict[key])是在统计这个模式字符对应了几个单词,但实际上,new_dict[key]存储的是一个单词字符串(比如'dog'),len()返回的是这个字符串的字符长度,'dog'有3个字符,所以结果是3,这完全是正常的函数行为,不是bug!你的判断逻辑从一开始就错了——你不需要检查单词的长度,而是要检查模式字符和单词之间的双射关系(也就是一一对应:一个模式字符只能对应一个单词,一个单词也只能被一个模式字符对应)。
你的现有代码逻辑问题
我们来看你代码里的核心逻辑:
for letter in list_pattern: if letter not in new_dict: new_dict[letter] = '' if list_str[c] not in new_dict[letter]: new_dict[letter] = list_str[c] c = c + 1
这段代码的问题在于:
- 它只维护了模式字符到单词的单向映射,没有检查反向的映射(比如如果两个不同的模式字符对应了同一个单词,你的代码不会发现)。
- 你的判断逻辑
len(new_dict[key]) !=1完全偏离了题目要求——题目不要求单词是1个字符,而是要求映射是一一对应的。
比如你的测试用例pattern="abba"和str="dog cat cat dog",其实是符合双射的,但你的代码因为检查单词长度(dog长度3≠1)错误地输出了false,最后又输出true,逻辑非常混乱。
正确的双射实现思路
要实现模式和单词的双射,我们需要维护两个映射:
- 一个字典
char_to_word:记录每个模式字符对应的单词。 - 另一个字典
word_to_char:记录每个单词对应的模式字符。
这样可以双向检查,确保一一对应。
同时,第一步要先检查pattern的长度和拆分后的单词列表长度是否相等,如果不等,直接返回False(比如模式是4个字符,但单词有5个,肯定不匹配)。
修正后的代码
def wordPattern(pattern, str): """ :type pattern: str :type str: str :rtype: bool """ words = str.split() # 首先检查长度是否一致,不一致直接返回False if len(pattern) != len(words): return False char_to_word = {} word_to_char = {} for char, word in zip(pattern, words): # 检查字符是否已经有映射 if char in char_to_word: if char_to_word[char] != word: return False else: # 如果字符没有映射,检查单词是否已经被其他字符映射了 if word in word_to_char: return False # 双向添加映射 char_to_word[char] = word word_to_char[word] = char # 所有检查都通过,返回True return True # 测试你的用例 print(wordPattern("abba","dog cat cat dog")) # 输出True print(wordPattern("abba","dog cat cat fish")) # 输出False print(wordPattern("aaaa","dog cat cat dog")) # 输出False
解释修正后的逻辑
- 先拆分单词并检查长度:如果模式字符数和单词数不一样,直接不匹配。
- 遍历每一对字符和单词:
- 如果字符已经在
char_to_word里,检查对应的单词是不是当前单词,不是就返回False。 - 如果字符不在映射里,先检查当前单词是不是已经被其他字符映射了(比如如果
dog已经被a映射,现在b又要映射dog,就返回False)。 - 如果都没问题,就把双向映射加上。
- 如果字符已经在
- 遍历完成后,说明所有映射都是一一对应的,返回True。
这样就能正确实现题目要求的双射判断啦!
内容的提问来源于stack exchange,提问作者Alexandra
相关产品推荐
相关产品推荐

