目录
题目
小明是 核心网工程师,客户交给小明一个任务:给定一个网络配置列表,每个配置是一个字符串,仅由数字和"*“、"?"符号组成。输入用户的IMSI(国际移动用户识别码),根据以下规则匹配配置列表:
"*"匹配0个或连续多个任意字符,
"?“匹配下标为奇数的单个字符,比如123?中的”?"可以匹配123456789012345下标为3的字符'4’,下标从0开始。
输入描述
输入第一行为 网络配置列表,列表中的每个配置是由数字和"*" ”?“组成的字符串,每个字符串中”*"不会超过一个,"?"若干,网络配置列表长度小于200,每个字符串以英文逗号隔开。
输入第二行为用户的IMSI(国际移动用户识别码),仅由数字组成,长度等于15.
备注
保证输入格式正确,无需考虑格式错误。
输出描述
输出为满足匹配规则的配置字符串列表,列表按字典序升序输出,每个字符以英文逗号隔开。若没有满足条件的配置,则返回字符串"null"示例1
输入:
1234567,1234567*
123456789012345输出:
1234567*
说明:
*可以匹配0或多个任意字符,故输出1234567*
示例2
输入:
123?????????345,123????*????345
123456789012345输出:
null
说明:"?"字符只能匹配IMSI中为奇数下标的字符,故都不符合要求,返回null
思路
简单的字符串匹配类型的题目,主要需要从题目中提取核心的逻辑:
- '*' 匹配0个或连续多个任意字符
- '?' 只能匹配奇数下标的单个字符
- 配置列表需要按字典序排序输出
- 没有匹配项时返回"null"
- 每个配置中'*'不会超过一个
- IMSI长度固定为15位数字
匹配过程中,针对两种特殊字符分别处理:
- 对于'*'的处理,将模式分割成前缀和后缀分别匹配
- 对于'?'的处理,检查是否在奇数下标位置
我这里给一个动态规划的解法吧。
状态定义:
dp[i][j] 表示模式串的前i个字符能否匹配IMSI的前j个字符
状态转移:
- * 的处理:可以匹配0个或多个字符,通过 dp[i-1][j] or dp[i][j-1] 来实现
- ? 的处理:只匹配奇数位置的字符,通过检查索引的奇偶性
- 普通字符:必须完全匹配
Code
def match_pattern(pattern: str, imsi: str) -> bool:
# 如果模式中没有特殊字符,直接比较
if '*' not in pattern and '?' not in pattern:
return pattern == imsi
# dp[i][j] 表示pattern的前i个字符能否匹配imsi的前j个字符
dp = [[False] * (len(imsi) + 1) for _ in range(len(pattern) + 1)]
# 空串匹配空串
dp[0][0] = True
# 处理只有*的情况可以匹配空串
for i in range(1, len(pattern) + 1):
if pattern[i-1] == '*':
dp[i][0] = dp[i-1][0]
# 填充dp数组
for i in range(1, len(pattern) + 1):
curr_char = pattern[i-1]
for j in range(1, len(imsi) + 1):
if curr_char == '*':
# *可以匹配0个或多个字符
# dp[i-1][j]表示不使用*
# dp[i][j-1]表示使用*匹配当前字符
dp[i][j] = dp[i-1][j] or dp[i][j-1]
elif curr_char == '?':
# ?只能匹配奇数位置的单个字符
if (j-1) % 2 == 1: # j-1是实际的索引
dp[i][j] = dp[i-1][j-1]
else:
# 普通字符必须完全匹配
dp[i][j] = dp[i-1][j-1] and curr_char == imsi[j-1]
return dp[len(pattern)][len(imsi)]
def solve_imsi_matching(configs: str, imsi: str) -> str:
# 分割配置字符串
patterns = configs.split(',')
# 存储匹配成功的配置
matched = []
# 检查每个配置是否匹配
for pattern in patterns:
if match_pattern(pattern, imsi):
matched.append(pattern)
# 如果没有匹配的配置,返回"null"
if not matched:
return "null"
# 按字典序排序并连接
return ','.join(sorted(matched))
# 主函数
def main():
# 读取输入
configs = input().strip()
imsi = input().strip()
# 输出结果
print(solve_imsi_matching(configs, imsi))
if __name__ == "__main__":
main()
【华为od机试真题Python+JS+Java合集】【超值优惠】:Py/JS/Java合集
【华为od机试真题Python】:Python真题题库
【华为od机试真题JavaScript】:JavaScript真题题库
【华为od机试真题Java】:Java真题题库
【华为od机试真题C++】:C++真题题库
【华为od机试真题C语言】:C语言真题题库
【华为od面试手撕代码题库】:面试手撕代码题库
【华为od机试面试交流群:830285880】【文章底部有二维码链接,可扫码加交流群】
华为OD机试:二本院校有机会吗?
有机会,但不大,大神除外!机考分数越高越好,所以需要提前刷题。机考通过后,如果没有收到面试邀请,也不要着急,非目标院校面试邀请发的时间比较晚。非目标院校今年有点难,机试至少要考到350分,所以需要疯狂刷题,华为OD机考是有题库的,最好在考前完所有题库题目。华为OD机试:跨专业可以参加华为OD可以,但是如果你的本科院校比较差,上岸概率不大。华为OD机试:华为OD简历被锁定机试通过,性格测试也通过,但是没人联系面试,发现简历被锁定。此时需要主动去联系HR。让他帮助你查询原因。