第 15 题
答案与解析
第(1)小题
人工
“大数据”与“数据”重叠,按长度优先保留“大数据”;其后匹配“推动”。
“人工智能”和“智能系统”都是4个字,且在“智能”处重叠,不能同时保留。二者词频分别为10和20,因此优先保留“智能系统”。它前面的“人工”也在词典中,可单独成词;最后的“发展”未出现在所给词典中,按单字划分。
分词结果为“大数据,推动,人工,智能系统,发,展”,第3个单词是“人工”。
第(2)①小题
[8,11,50,3]
程序分析
p=head
q=words[p][3]
while q!=-1 and (words[q][2]>=node[2] or node[0]>words[q][1]):
p=q
q=words[q][3]题干规定每个结点依次保存词语的开始索引、结束索引、词频和后继结点下标。前三项为-1的words[head]是辅助头结点,不代表实际词语。
p先指向辅助头结点,q取得它的后继结点下标。循环中先令p=q,再令q=words[q][3],使二者沿链表向后移动,p始终指向q所指结点的前驱。q为-1表示已到链表末尾;否则,只有括号中的条件成立,才继续跳过当前结点。
words.append(node)
words[p][3]=len(words)-1
words[len(words)-1][3]=q
return wordsappend把新结点追加到列表末尾,其下标为len(words)-1。随后把p所指结点的后继改为新结点,再把新结点的后继设为q,从而将新结点插在p与q之间。若q为-1,则接到链表末尾。列表中的存储位置与链表中的先后次序由指针联系,不必相同。
新词的开始索引为8、词频为50。沿链表检查:
| q | 词频条件 | 位置条件 | 操作 |
|---|---|---|---|
| 1 | 40≥50不成立 | 8>5成立 | 跳过结点1 |
| 2 | 32≥50不成立 | 8>3成立 | 跳过结点2 |
| 3 | 25≥50不成立 | 8>9不成立 | 停止查找 |
循环结束时p=2、q=3。新结点追加到words[4],其后继设为3,因此words[4]为[8,11,50,3];同时words[2][3]改为4。
第(2)②小题
D
共用程序分析见第(2)①小题。
q不为-1时,括号内用or连接两个条件,任一条件成立就跳过当前结点:
- words[q][2]>=node[2]:当前词的词频不低于新词,包含词频相等的情况。
- node[0]>words[q][1]:新词的开始索引大于当前词的结束索引,即当前词完全位于新词之前,二者没有重叠文字。
这与D项的表述一致。
第(3)小题
word=text[i:i+j]
cur,start
p[i]!=-1 and end>=words[p[i]][0]
程序分析
text=input("输入文本:")
result = split(text,dict,max_word_len)
print("分词结果:",result)主程序输入待分词文本,将文本、词典和词典中最长词语的长度传给split函数,最后输出函数返回的分词结果。下面按split中的执行顺序分析。
n = len(text)
words = []
for i in range(max_word_len+1):
words.append([-1,-1,-1,-1])
for i in range(n):
for j in range(2,max_word_len+1):
if i+j <= n:
①
weight=search(dict,word)
if weight!=-1:
insert(words,j,[i,i+j-1,weight,-1])程序先在words中建立max_word_len+1个辅助头结点。随后i遍历文本的起始位置,j遍历2到max_word_len的词长;i+j<=n保证从i开始的j个字符没有超出文本范围。
search返回候选词的词频,返回-1表示词典中不存在该词。找到匹配词时,结点保存[i,i+j-1,weight,-1],即词语在text中的起止索引、词频和后继指针,并调用insert插入以words[j]为辅助头结点的链表。由此可知,不同词长使用不同链表,同一链表中的候选词长度相同;结点的前两项是文本索引,最后一项则是后继结点在words中的下标。
p=[-1]*(max_word_len+1)
for i in range(2,max_word_len+1):
p[i]=words[i][3]
res=""
cur=0
while hasmore(p):
...words[i][3]取得长度为i的链表中首个候选结点的下标,并保存到p[i],所以p[i]指向该长度当前待处理的候选词;-1表示没有候选词。res初始化为空字符串,cur初始化为0。hasmore逐项检查p[2]到p[max_word_len],只要还有一个不为-1,就继续处理。
x=-1
for i in range(max_word_len,1,-1):
if p[i]!=-1 and (x==-1 or words[p[i]][1]<words[p[x]][0]):
x=i
start=words[p[x]][0]
end=words[p[x]][1]i按词长从大到小变化。x为-1时,遇到第一个非空链表就令x=i;已有候选后,只有当前较短词的结束索引小于已选词的开始索引,才改选较短词。这样,较短词完全位于已选词之前时可先处理它;若二者重叠,则保留先选中的较长词。
x保存所选词的长度,p[x]才是该词结点在words中的下标。通过这个结点取得start和end,即所选词在text中的起止索引。
for i in range(②):
res+=text[i]+","
res+=text[start:end+1]+","
cur=end+1第一个循环逐字追加字符和分隔逗号,随后将选中的整个词追加到res。选词结束后,cur更新为end+1,表示下一次尚未处理的字符位置;结合其初值0,可知处理范围从文本开头逐步向后推进。
for i in range(max_word_len,1,-1):
while ③:
p[i]=words[p[i]][3]程序依次检查各词长的当前候选。p[i]=words[p[i]][3]沿该链表移到后继结点,从当前候选开始连续跳过已失效的词。words中的旧结点仍然存在,改变的是各链表下一次参与选择的位置。
for i in range(cur,n):
res+=text[i]+","
return res所有候选词都处理完后,cur之后可能还有字符未加入结果。程序把这些剩余字符逐字追加,再返回res。若从未匹配到词语,cur仍为0,这个循环便将全文按单字划分。
填空分析
①
当前起始索引为i、词长为j,需要取出从i到i+j-1的字符交给search查找。Python切片不包含右端点,因此填写:
word=text[i:i+j]
②
cur是尚未处理的起始位置,start是本轮所选词的开始索引。在追加整个词之前,应先将cur到start-1之间的字符按单字追加,故range的两个参数为:
cur,start
若cur等于start,循环为空,直接追加所选词。
③
所选词追加后,下标不大于end的字符已经处理过。当前候选若从这些位置开始,就已被处理或与已选词重叠,应沿链表跳过。因此需判断候选词的开始索引words[p[i]][0]是否不大于end。
访问结点前还须保证p[i]!=-1,否则已经没有候选词。用and连接,使指针为-1时不再访问结点,填写:
p[i]!=-1 and end>=words[p[i]][0]
判断包含等号:候选词若恰好从end开始,仍与已选词共用最后一个字符。
问题反馈
解析有疑问或显示异常?请先复制题目信息,再打开反馈表单填写。
题目编号:2026_05_G3_yiwukeqiaomoni_q015
