注意文本的格式,建議UTF-8防止出現不可見字符導致無法匹配
class CSegment:
def __init__(self, MaxLen, seg):
self.MaxLen = MaxLen # 初始化MaxLen
self.seg = seg # 初始化分隔符
# 初始化詞典(數據類型爲dict)
self.Dict=[]
self.setDict()
# 初始化分詞結果
self.result = []
def setDict(self):
# 打開詞典文件
file = open("D:\\chineseDic.txt",
mode='r')
# 添加到詞典中
for line in file:
self.Dict[line.split(',')[0]]=1
#Dict可以O(1)查找,下面list是O(m)
#self.Dict.append(line.split(',')[0])
def MM(self, sentence): # 正向最大匹配
indexpos, Len = 0, self.MaxLen
while indexpos < len(sentence): # 順序掃描
str_ = sentence[indexpos:indexpos + Len] # 從待切分語料中正向取長度爲 MaxLen 的字串 str_
if str_ in self.Dict or len(str_) == 1: # 匹配成功,list和dict都是這樣寫
self.result.append(str_) # 將結果添加到result詞典中
indexpos, Len = indexpos + Len, self.MaxLen # indexpos向後移動, Len復位爲MaxLen
else:
Len -= 1
# 根據seg自動返回切分好的句子
return "{}".format(self.seg).join(self.result)
def RMM(self, sentence): # 反向最大匹配
indexpos, Len = len(sentence), self.MaxLen
while indexpos > 0:
# 從待切分語料中反向取長度爲 MaxLen 的字串 str_
str_ = sentence[indexpos - Len:indexpos]
if str_ in self.Dict or len(str_) == 1:
self.result.append(str_) # 匹配成功
indexpos, Len = indexpos - Len, self.MaxLen # indexpos向前移動, Len復位
else:
Len -= 1
# 根據seg自動返回切分好的句子
return "{}".format(self.seg).join(self.result[::-1])
def getResult(self, ans: str, seg: str):
M = ans.split(seg) # 標準答案集
N = self.result # 實際測試結果
n = [i for i in M if i in N] # M ∩ N
try:
P = len(n) / len(N)
R = len(n) / len(M)
F = (2 * P * R) / (P + R)
except ZeroDivisionError: # 一個詞都沒有分對
P, R, F = 0, 0, 0
# 百分號格式化(輸出)
return "結果: \nP:{:.3%}\nR:{:.3%}\nF:{:.3%}".format(P, R, F)
def main():
sentence = input("輸入待分詞句子: \n")
MaxLen = int(input("MaxLen = "))
seg = input("輸入切分符號: ")
ans = input("輸入標準文本串: \n")
print("MM:")
MMCutter = CSegment(MaxLen=MaxLen, seg=seg)
print(MMCutter.MM(sentence=sentence))
print(MMCutter.getResult(ans=ans, seg=seg))
print("RMM:")
RMMCutter = CSegment(MaxLen=MaxLen, seg=seg)
print(RMMCutter.RMM(sentence=sentence))
print(RMMCutter.getResult(ans=ans, seg=seg))
main()