from dict_3 import word_sum,word_dict,word2_dict

word_count = len(word_dict) 
#判断字符ch是否为汉字
def isKannji(ch):
    by = bytes(ch,encoding='gbk')
    #小于两个字节是英文字符
    if len(by) < 2:
        return False
    #排除各种符号
    if (by[0] >= 0xa1 and by[0] <= 0xa9):
        return False
    # if ch in ['，','；','。','、','：','！','【','】','■','‘','’','●','□','（','）']:
    #     return False
    return True

def PreDivSentense(sen):
    word = list()
    str_bak = ''
    str_new = ''
    for i in sen:
        if (not isKannji(i)):
            #不是汉字时直接分词
            if str_bak is not '':
                word.append(str_bak)
            word.append(i)
            str_bak = ''
            str_new = ''
            continue
        str_new = str_bak + i 

        if str_bak == '':
            str_bak = i
        #增长后的字符串在词表中不存在
        if str_new not in word_dict:
            word.append(str_bak)
            str_bak = i
            continue
        else:
            str_bak = str_new
    if str_bak is not '':
        word.append(str_bak)
    #for w in word:
    #    print(w+'|',end='')
        
    return word

def BakDivSentense(sen):

    word = list()
    sen = sen[::-1]
    str_bak = ''
    str_new = ''
    for i in sen:
        if (not isKannji(i)):
            #不是汉字时直接分词
            if str_bak is not '':
                word.append(str_bak)
            word.append(i)
            str_bak = ''
            str_new = ''
            continue

        str_new = i + str_bak

        if str_bak == '':
            str_bak = i
        #增长后的字符串在词表中不存在
        if str_new not in word_dict:
            word.append(str_bak)
            str_bak = i
            continue
        else:
            str_bak = str_new
    if str_bak is not '':
        word.append(str_bak)
    word = word[::-1]
    #for w in word:
    #    print(w+'|',end='')
    return word
def pstr(s1,s2):

    try:
        c_s1_s2 = word2_dict[s1+' '+s2]
    except:
        c_s1_s2 = 0


    if s1 not in word_dict:
    #认为未登录词出现次数为0
    #由于没统计<BOS>出现的次数，假设<BOS>次数为0
        return (1.0+c_s1_s2)/(word_count)
    else:
        return (1.0+c_s1_s2)/(word_count+word_dict[s1])


#计算字符串s出现的概率s->list
def CalcP(s):
    if len(s)<=2:
        return 1.0
    p = 1.0
    for i in range(len(s)-1):
        p = p * pstr(s[i],s[i+1])
    return p

def PrintDivSen(s):
    r = ''
    for i in range(1,len(s)-2):
        r += s[i] + ' '
    r += s[-2]
    return r
    

def DivSentense(sen):
    bakdiv = BakDivSentense(sen)
    #print('')
    prediv = PreDivSentense(sen)
    ret = ''
    #print('')
    d1 = ['<BOS>']
    d2 = ['<BOS>']
    i1 = 0
    i2 = 0
    while True:
        if i1 >= len(prediv) or i2 >= len(bakdiv):
            break
        if len(prediv[i1])==1 and not isKannji(prediv[i1]):
            #长度为1，且不是汉字，就是标点符号，直接输出
            ret += prediv[i1]
            i1+=1
            i2+=1
            continue

        while i1 < len(prediv) and (len(prediv[i1])>=2 or isKannji(prediv[i1]))  :

            d1.append(prediv[i1])
            i1+=1

        d1.append('<EOS>')
        p1 = CalcP(d1)
        #计算后向算法分句概率
        while  i2 < len(bakdiv) and (len(bakdiv[i2])>=2 or isKannji(bakdiv[i2]))  :
            d2.append(bakdiv[i2])
            i2+=1



        d2.append('<EOS>')
        p2 = CalcP(d2)

        #前向算法断句概率更高
        if (p1 >= p2):
            ret += PrintDivSen(d1)
        else:
            ret += PrintDivSen(d2)

        if i1 >= len(prediv) or i2 >= len(bakdiv):
            break

        #输出标点符号
        ret += prediv[i1]

        i1+=1
        d1 = ['<BOS>']

        i2+=1
        d2 = ['<BOS>']

    return ret

#CalcP(('<BOS>','文山','须','平','<EOS>'))

#sentense = "实行会议费等预警止付机制，严控会议数量、规模和规格，实现总量可控、逐年下降。"

from tkinter import * 

window = Tk()
window.title('断句')
Label(window,text='文本：').grid(row=0,column=0)

name_in = Text(window,height=10, width=50)
name_in.grid(row=0,column=1)

pome_out = Text(window,height=12, width=50)
pome_out.grid(row=4,column=1)

def divSen():

    #name = input('词牌名')
    ins = name_in.get(0.0,END).strip(" ").strip('\n')
    
    output = DivSentense(ins)
    print(output)
    pome_out.delete(0.0, END)
    pome_out.insert(0.0,output)


Button(window,text='生成',command=divSen).grid(row=2,column=2)

Label(window,text='结果:').grid(row=4,column=0)


mainloop()

'''新华社北京10月10日电中共中央总书记、国家主席、中央军委主席、中央财经委员会主任习近平10月10日下午主持召开中央财经委员会第三次会议,研究提高我国自然灾害防治能力和川藏铁路规划建设问题。习近平在会上发表重要讲话强调,加强自然灾害防治关系国计民生,要建立高效科学的自然灾害防治体系,提高全社会自然灾害防治能力,为保护人民群众生命财产安全和国家安全提供有力保障；规划建设川藏铁路,对国家长治久安和西藏经济社会发展具有重大而深远的意义,一定把这件大事办成办好。'''

'''中国公安部10日在北京召开视频会议，部署自即日起，组织全国公安机关开展为期3个月的深化打击食品药品农资和环境犯罪行动，突出打击治理民生领域犯罪问题，切实维护广大人民群众生命财产安全和身体健康。

　　今年以来，截至目前，各地共破获食品药品农资和环境犯罪案件2.1万余起，抓获犯罪嫌疑人2.6万余名。但食品药品农资和环境犯罪点多、面广、量大，新情况新问题不断出现，涉网案件高发频发，跨国跨境跨区域犯罪突出，网上网下违法犯罪交织勾连，社会危害严重。对此，公安部党委高度重视、多次部署依法打击。

　　公安部副部长孙力军在视频会议上强调，各地公安机关要重拳出击，以对食品药品农资和环境违法犯罪“零容忍”的态度，全力侦破一批大要案件。'''
sentense = "文山须平、会海要填，关键是加强源头治理。各级领导干部应树立正确的政绩观，坚持问题导向，带头改进文风会风，精简文件和会议。开多少会、发多少文，要有科学规划，实行清单管理，对未纳入清单的文件与会议，坚决不发、不开，必须开的会议开出质量和实效，实行会议费等预警止付机制，严控会议数量、规模和规格，实现总量可控、逐年下降。"
print(DivSentense(sentense))