首页 > 代码库 > 基于trie树的具有联想功能的文本编辑器
基于trie树的具有联想功能的文本编辑器
之前的软件设计与开发实践课程中,自己构思的大作业题目。做的具有核心功能,但是还欠缺边边角角的小功能和持久化数据结构,先放出来,有机会一点点改。github:https://github.com/chuxiuhong/smarteditor
数据结构,使用过程截图以及源代码如下:
#数据结构
**trie树**
trie树相应的介绍点击链接[https://en.wikipedia.org/wiki/Trie](https://en.wikipedia.org/wiki/Trie)
trie树在python文件中的类型定义
Node定义
#GUI设计界面
首先,用较大的文本文件进行训练,完成trie的树的训练。本文件夹下提供了一个big2.txt文件作为示例。
在之后的输入会弹出提示框
#!/usr/bin/python# -*- coding: utf-8 -*-import PyQt4from PyQt4.QtCore import *from PyQt4.QtGui import *import PyQt4.QtCoreimport sysimport pickleprint ‘===================start=======================‘class Node: def __init__(self): self.value = None self.children = {} # children is of type {char, Node} self.fre = 0 self.father = Nonedef CMP(a, b): return b.fre - a.freclass Trie: def __init__(self): self.root = Node() self.choose = [] self.__OpenCorrect__ = 0 def insert(self, key): # key is of type string # key should be a low-case string, this must be checked here! node = self.root for char in key: if char not in node.children: child = Node() node.children[char] = child child.value = char child.father = node node = child else: node = node.children[char] # node.value = http://www.mamicode.com/key node.fre += 1 def search(self, key): node = self.root for char in key: if char not in node.children: return None else: node = node.children[char] return node.value def display_node(self, node): if (node.value != None): print node.value for char in ‘abcdefghijklmnopqrstuvwxyz‘: if char in node.children: self.display_node(node.children[char]) return def fallback(self, node): f_char = ‘‘ while node != self.root: f_char = node.value + f_char node = node.father # print f_char return f_char def display(self): self.display_node(self.root) def find_node(self, string): res_node = self.root for i in string: res_node = res_node.children[i] return res_node def association(self, node): # 调用此函数前应该先将self.choose恢复成空列表 if (node.value != None): if node.fre > 0: self.choose.append(node) for char in ‘abcdefghijklmnopqrstuvwxyz‘: if char in node.children: self.association(node.children[char]) def output_association(self, char): char = str(char).lower() self.choose = [] result_list = [] self.association(self.find_node(char)) self.choose.sort(cmp=CMP) if len(self.choose) > 0: for i in self.choose: result_list.append(self.fallback(i)) if self.__OpenCorrect__ == 0: result_list.insert(1, self.correct(char)) # print ‘result_list‘,result_list return result_list def correct(self, string): self.choose = [] p = self.find_node(string[:-1]) self.association(p) self.choose.sort(cmp=CMP) if len(self.choose) > 1: return self.fallback(self.choose[0])def train(trie, path): # f = open(r‘big2.txt‘) f = open(path) word = f.read() f.close() word = word.split(‘ ‘) for i in word: trie.insert(i)trie = Trie()trie.__OpenCorrect__ = 0def save_model(T): f1 = open("trie.pkl", ‘wb‘) pickle.dump(T, f1) f1.close()def load_model(path): f2 = open(path, ‘rb‘) trie = pickle.load(f2) f2.close()print ‘================= END =====================‘class UI(QDialog): def __init__(self, parent=None): super(UI, self).__init__(parent) QSList = QStringList() # default # QSList<<‘One‘<<‘Tow‘<<‘Three‘<<‘Four‘<<‘Five‘ # instance of Completer class cmp = Completer(QSList) global edit edit = TextEdit() edit.setFontPointSize(80) edit.setCompleter(cmp) self.setWindowTitle(u"智能文本编辑器") button1 = QPushButton(u"训练模型") button2 = QPushButton(u"保存文本文件") button3 = QPushButton(u"打开文本文件") ‘‘‘ buttons = QushButton() ‘‘‘ ‘‘‘ 定义按钮,()内为按钮名称 ‘‘‘ self.connect(button1, SIGNAL("clicked()"), self.get_file) self.connect(button2, SIGNAL("clicked()"), self.func2) self.connect(button3, SIGNAL("clicked()"), self.func3) ‘‘‘ 关联按钮与函数格式同上,触发为clicked()单击,最后一个参数为 类内函数 ‘‘‘ layout = QGridLayout() layout.addWidget(edit, 0, 1, 1, 5) layout.addWidget(button1, 2, 1) layout.addWidget(button2, 2, 3) layout.addWidget(button3, 2, 5) ‘‘‘ 按钮布局 ‘‘‘ self.setLayout(layout) self.center() def center(self): screen = QDesktopWidget().screenGeometry() size = self.geometry() self.move((screen.width() - size.width()) / 2, (screen.height() - size.height()) / 2) def get_file(self): s = QFileDialog.getOpenFileName(self, "Open file dialog", "/", "TXT Files(*.txt)") train(trie, s) def func2(self): s = QFileDialog.getSaveFileName(self, "文件保存", "C:/", "All Files (*);Text Files (*.txt)") f = open(s, ‘w‘) f.write(edit.toPlainText()) f.close() def func3(self): s = QFileDialog.getOpenFileName(self, "Open file dialog", "/", "TXT Files(*.txt)") f = open(s) edit.setText(PyQt4.QtCore.QString(f.read())) f.close()class TextEdit(QTextEdit): def __init__(self, parent=None): super(TextEdit, self).__init__(parent) self.cmp = None self.p = ‘‘ self.count = 0 def setCompleter(self, completer): if self.cmp: self.disconnect(self.cmp, 0, 0) self.cmp = completer if (not self.cmp): return self.cmp.setWidget(self) self.cmp.setCompletionMode(QCompleter.PopupCompletion) self.cmp.setCaseSensitivity(Qt.CaseInsensitive) self.connect(self.cmp, SIGNAL(‘activated(QString)‘), self.insertCompletion) def completer(self): return self.cmp def insertCompletion(self, string): # get cursor position tc = self.textCursor() # selectd ranges tc.movePosition(QTextCursor.StartOfWord, QTextCursor.KeepAnchor) # replace selected ranges tc.insertText(string) self.p += str(string) # set cursor pos back to original pos self.setTextCursor(tc) def textUnderCursor(self): tc = self.textCursor() tc.select(QTextCursor.WordUnderCursor) return tc.selectedText() def keyPressEvent(self, e): ‘‘‘ if e.key() != Qt.Key_Backspace: self.p = self.p + e.text() self.count+=1 print ‘yes‘ else: self.p = self.p[:-1] self.count-=1 ‘‘‘ print ‘p ‘, self.p print ‘pressed >> ‘, e.text() if (self.cmp and self.cmp.popup().isVisible()): if e.key() in (Qt.Key_Enter, Qt.Key_Return, Qt.Key_Escape, Qt.Key_Tab, Qt.Key_Backtab): e.ignore() return isShortcut = ((e.modifiers() & Qt.ControlModifier) and e.key() == Qt.Key_E) if (not self.cmp or not isShortcut): super(TextEdit, self).keyPressEvent(e) ctrlOrShift = e.modifiers() & (Qt.ControlModifier | Qt.ShiftModifier) if (not self.cmp or (ctrlOrShift and e.text().isEmpty())): return eow = QString("~!@#$%^&*()_+{}|:\"<>?,./;‘[]\\-=") hasModifier = (e.modifiers() != Qt.NoModifier) and not ctrlOrShift completionPrefix = self.textUnderCursor() # hide popup while matching invalid cases if (not isShortcut and (hasModifier or e.text().isEmpty() or completionPrefix.length() < 1 or eow.contains(e.text().right(1)))): self.cmp.popup().hide() return self.cmp.update(completionPrefix) self.cmp.popup().setCurrentIndex(self.cmp.completionModel().index(0, 0)) cr = self.cursorRect() cr.setWidth(self.cmp.popup().sizeHintForColumn(0) + self.cmp.popup().verticalScrollBar().sizeHint().width()) word = self.p.split(‘ ‘)[:-1] self.p = ‘‘ for k in xrange(len(word)): self.p += word[k] print ‘self.p=‘, self.p self.cmp.complete(cr)class Completer(QCompleter): def __init__(self, stringlist, parent=None): super(Completer, self).__init__(parent) self.stringlist = stringlist self.setModel(QStringListModel()) # update function will trigger while the text has been modified def update(self, completionText): # generate a new QStringList instance qsList = QStringList() # generate hint lists which returns by customatic definitions newList = genMyStrList(completionText) for item in newList: qsList.append(item) self.stringlist = qsList # filteredList = self.stringlist.filter(completionText, Qt.CaseInsensitive) self.model().setStringList(self.stringlist) self.popup().setCurrentIndex(self.model().index(0, 0))# the function below defined a way to generate a string listdef genMyStrList(key): my_str_list = trie.output_association(key) return my_str_listdef main(): app = QApplication(sys.argv) app.processEvents() form = UI() form.show() # splash.finish(form) app.exec_() window = QMainWindow() window.statusBar().showMessage(‘Yuan Ziqi‘) menubar = window.menuBar window.setWindowTitle(‘Auto Complete Demo‘) window.resize(400, 200) window.move(400, 100) edit = TextEdit() edit.setFontPointSize(40) edit.setCompleter(cmp) # bt = addbutton() # window.addDockWidget(bt) window.setCentralWidget(edit) window.show() sys.exit(app.exec_())if __name__ == ‘__main__‘: print ‘app is running successfully‘ main()
基于trie树的具有联想功能的文本编辑器
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。