赞
踩
给定一个连续不包含空格的字符串,该字符串仅包含英文小写字母及英文标点符号(逗号、分号、句号),同时给定词库,对该字符串进行精确分词。分词原则:采用分词顺序优先且最长匹配原则
输入描述:
第一行输入待分词语句 “ilovechina”,字符串长度限制:0 < length < 256
第二行输入中文词库 “i,love,china,ch,na,ve,lo,this,is,this,word”,词库长度限制:1 < length < 100000
输出描述:
按顺序输出分词结果 “i,love,china”
# 定义 TrieNode 类,每个节点包含一个布尔值 is_word 和一个 TrieNode 类型的数组 children
class TrieNode:
def __init__(self):
self.is_word = False # 标记该节点是否为一个单词的结束
self.children = [None] * 26 # 存储子节点的数组,每个元素对应一个字母
# 创建 Trie 的根节点
root = TrieNode()
# 插入方法,用于向 Trie 中插入一个单词
def insert(word):
node = root # 从根节点开始
for i in word:
index = ord(i) - ord('a') # 计算当前字符对应的索引
# 如果当前字符对应的子节点为空,则创建一个新的子节点
if node.children[index] is None:
node.children[index] = TrieNode()
# 移动到下一个子节点
node = node.children[index]
# 标记当前节点为一个单词的结束
node.is_word = True
# 输入句子,并将其转换为小写
sentence = input().lower()
# 输入字典,字典中的单词以逗号分隔
dictionary = input().split(",")
for word in dictionary:
insert(word.lower()) # 将字典中的每个单词插入到 Trie 中
result = [] # 存储结果
i = 0
# 遍历句子中的每个字符
while i < len(sentence):
# 如果当前字符i不是字母,则直接将其添加到结果中
if not sentence[i].isalpha():
result.append(sentence[i])
i += 1
continue # 跳过此次迭代,继续下一次迭代
# 如果当前字符i是字母,则从句子的末尾开始,寻找以该字符为起点的最长的在字典中存在的单词
j = len(sentence)
while j > i:
node = root
complete = True
for k in range(i, j):
# 如果当前字符不是字母,或者在 Trie 中不存在当前字符对应的节点,则说明i:j字符串不是一个单词,终止for循环
if not sentence[k].isalpha() or node.children[ord(sentence[k]) - ord('a')] is None:
complete = False
break # 终止循环,不再执行后续的迭代
# 如果当前字符是字母,且在 Trie 中存在当前字符对应的节点,则移动到下一个子节点继续判断
node = node.children[ord(sentence[k]) - ord('a')]
# 如果i:j字符串是一个单词,则终止while循环
if complete and node.is_word:
break
# 如果i:j字符串不是一个单词,则缩短该字符串
j -= 1
# 如果没有找到单词,则将当前字符作为一个单独的单词添加到结果中
if j == i:
result.append(sentence[i])
i += 1
# 如果找到了单词,则将该单词添加到结果中
else:
result.append(sentence[i:j])
i = j
# 输出结果,单词之间以逗号分隔
print(",".join(result))
“手机App 防沉迷系统”能够让每天合理地规划手机 App 使用时间,在正确的时间做正确的事。它的大概原理是这样的:在一天 24 小时内,可以注册每个 App 的允许使用时段一个时间段只能使用一个 App。请编程实现,根据输入数据注册 App,并根据输入的时间点,返回时间点使用的App 名称,如果该时间点没有注册任何 App,请返回字符串“NA”。
优先级 1~5,数字越大,优先级越高;注册使用时段时,如果高优先级的App时间和低优先级的时段有冲突,则系统会自动注销低优先级的时段;如果App的优先级相同,则后添加的 App 不能注册。时间格式 HH:MM,小时和分钟都是两位,不足两位前面补0;起始时间需小于结束时间,否则注册不上;注册信息中的时间段包含起始时间点,不包含结束时间点。
输入描述:
第一行表示注册的 App 数量 N(N ≤ 100)。
第二部分包括 N 行,每行表示一条 App 注册数据,数据以空格分隔,四项数依次表示:App 名称、优先级、起始时间、结束时间。
最后一行输入一个时间点,程序需返回该时间点可以使用的App。
输出描述:
输出一个字符串,表示 App 名称,或 NA 表示空闲时间。
from datetime import datetime
# 定义 App 时间段类
class AppTimeSlot:
def __init__(self, app_name, priority, start_time, end_time):
self.app_name = app_name # App 名称
self.priority = priority # 优先级
self.start_time = start_time # 开始时间
self.end_time = end_time # 结束时间
# 将字符串解析为固定格式的 datetime 对象的方法
@staticmethod # 静态方法可以直接通过类名调用,而不需要创建类的实例。但不具有访问实例属性的能力,定义时不需要传递 self 参数。
def norm_time(time_str):
return datetime.strptime(time_str, "%H:%M")
# 注册 App 时间段的方法
def app_register(self, app_list):
conflict = False
# 检查优先级高于或等于新时间段的现有时间段,若与新时间段冲突则不注册新时间段
for slot in app_list:
if slot.priority >= self.priority and slot.start_time < self.end_time and slot.end_time > self.start_time:
conflict = True
break
# 若不冲突则注册新时间段
if not conflict:
app_list.append(self)
# 检查优先级低于新时间段的现有时间段,移除与新时间段冲突的现有时间段
for slot in app_list:
if slot.priority < self.priority and slot.start_time < self.end_time and slot.end_time > self.start_time:
app_list.remove(slot)
return app_list
# 获取指定时间点正在使用的 App 名称
@staticmethod
def get_app_at_time(app_list, query_time):
for slot in sorted(app_list, key=lambda x: (-x.priority, x.start_time)):
if slot.start_time <= query_time < slot.end_time:
return slot.app_name
return "NA"
# 主程序
count = int(input())
# 构建App注册表
app_list = []
for _ in range(count):
app_name, priority_str, start_time_str, end_time_str = input().split()
priority = int(priority_str)
start_time = AppTimeSlot.norm_time(start_time_str) # 调用静态方法 time()
end_time = AppTimeSlot.norm_time(end_time_str) # 调用静态方法 time()
new_app = AppTimeSlot(app_name, priority, start_time, end_time) # 定义实例对象
app_list = new_app.app_register(app_list) # 使用实例方法 register_app()
# 查询某时间段的可用App
query_time_str = input()
query_time = AppTimeSlot.norm_time(query_time_str) # 调用静态方法 time()
result = AppTimeSlot.get_app_at_time(app_list, query_time)
print(result)
注:从此题可以体会到类中的方法和函数的区别:实例方法可以不用传参而直接使用对象的属性;静态方法和函数一样不能访问对象的属性,但是封装性更好。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。