注意文本的格式,建议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()