马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
#加载词前缀词典
#用0和1来区分是前缀还是真词
#需要注意有的词的前缀也是真词,在记录时不要互相覆盖
def load_prefix_word_dict(path):
prefix_dict = {}
with open(path, encoding="utf8") as f:
for line in f:
word = line.split()[0]
for i in range(1, len(word)):
if word[:i] not in prefix_dict: #不能用前缀覆盖词
prefix_dict[word[:i]] = 0 #前缀
prefix_dict[word] = 1 #词
return prefix_dict
#输入字符串和字典,返回词的列表
def cut_method2(string, prefix_dict):
if string == "":
return []
words = [] # 准备用于放入切好的词
start_index, end_index = 0, 1 #记录窗口的起始位置
window = string[start_index:end_index] #从第一个字开始
find_word = window # 将第一个字先当做默认词
while start_index < len(string):
#窗口没有在词典里出现
if window not in prefix_dict or end_index > len(string):
words.append(find_word) #记录找到的词
start_index += len(find_word) #更新起点的位置
end_index = start_index + 1
window = string[start_index:end_index] #从新的位置开始一个字一个字向后找
find_word = window
#窗口是一个词
elif prefix_dict[window] == 1:
find_word = window #查找到了一个词,还要在看有没有比他更长的词
end_index += 1
window = string[start_index:end_index]
#窗口是一个前缀
elif prefix_dict[window] == 0:
end_index += 1
window = string[start_index:end_index]
#最后找到的window如果不在词典里,把单独的字加入切词结果
if prefix_dict.get(window) != 1:
words += list(window)
else:
words.append(window)
return words
我不理解的地方是为什么要有
if prefix_dict.get(window) != 1:
words += list(window)
else:
words.append(window)
这一段代码
按照注释的意思是说,“最后找到的window如果不在词典里,把单独的字加入切词结果”
但是来看cut_method2函数的while循环
循环退出的条件是当开始索引start_index等于或者大于字符串的长度的时候
但是
在while的代码块中,只有“if window not in prefix_dict or end_index > len(string)”这个判断语句后的代码块中有更新start_index的操作
也就是说,如果我下一轮要退出while循环了
那么我这一轮一定进入的是“if window not in prefix_dict or end_index > len(string)”这个判断语句后的代码块
然后这一轮由“start_index += len(find_word)”这句代码,我的start_index大于或等于字符串长度了
(但是我感觉start_index最多就是等于len(string),不可能大于len(string)了,不知道是不是我理解有误)
假设等于len(string),那么end_index=start_index+1,所以此时进行string[start_index:end_index]这个切片操作,已经在string中切不到任何东西了
因为开始索引就已经大于字符串长度了
所以在下一轮退出循环的时候,window中没有任何东西,也就不需要上面提到的那段代码了
请大佬们指正我的理解是否正确 |