指令前缀既能结束又能继续时怎样组织提示:机制演算第20例
自动补全中,一个前缀可能已经是一条完整指令,同时还通向更长的指令。若只把叶子当成完整项,就会漏掉这种两种身份同时存在的节点。
将每条指令逐字符放入前缀树,完整指令在结束节点记录自身使用次数。查询前缀后,分别列出它是否完整、下一层可选字符,以及所有后代完整指令中使用次数最高的三项,同次数按字母顺序。
本例的输入和输出
完整指令及使用次数为{'GET': 4, 'GO': 14, 'GOTO': 10, 'LEAVE': 20, 'LOAD': 18, 'LOCK': 10, 'LOOP': 5, 'MAP': 16, 'MARK': 9, 'MOVE': 5, 'PAUSE': 8, 'PICK': 18, 'PORT': 2, 'SAVE': 11, 'SEND': 1, 'SET': 12}。没有记录的指令不属于当前集合。
查询前缀 | 路径存在 | 自身完整指令次数 | 下一字符 | 前三项 空前缀 | True | 0 | ['G', 'L', 'M', 'P', 'S'] | [['LEAVE', 20], ['LOAD', 18], ['PICK', 18]] G | True | 0 | ['E', 'O'] | [['GO', 14], ['GOTO', 10], ['GET', 4]] GO | True | 14 | ['T'] | [['GO', 14], ['GOTO', 10]] LO | True | 0 | ['A', 'C', 'O'] | [['LOAD', 18], ['LOCK', 10], ['LOOP', 5]] P | True | 0 | ['A', 'I', 'O'] | [['PICK', 18], ['PAUSE', 8], ['PORT', 2]] S | True | 0 | ['A', 'E'] | [['SET', 12], ['SAVE', 11], ['SEND', 1]] LOCK | True | 10 | [] | [['LOCK', 10]] LO | True | 0 | ['A', 'C', 'O'] | [['LOAD', 18], ['LOCK', 10], ['LOOP', 5]] MZ | False | 0 | [] | [] PI | True | 0 | ['C'] | [['PICK', 18]]
表格中的编号只标识当前例子的元素,不应把对象身份、数组下标与计算数值混为一谈。阅读时先核对输入和边界,再沿记录检查每一步;空结果表示规则下没有可用项,并不是默认返回数值零。
复核与适用条件
节点没有孩子不等于查询失败,节点有孩子也不等于它不能结束。前缀为空时查询整个指令集;前缀不存在时返回空结果。使用次数只属于完整指令,不能混成经过该节点的总次数。
本例只使用大写英文字符,未处理大小写折叠、拼写纠错或多语言文字。提示排序是本文规定的频次优先模型,不代表最近使用或最适合当前场景,实际界面还应结合自身的可用指令范围。
练习时先独立复算一小段,再检查整体结果是否满足文中条件。遇到差异应保留中间记录并定位第一处不一致,而不是只调整最后答案。更换输入或操作规则后,需要重新计算,原记录只对这一例负责。
