问题描述
在广告平台中,为了给广告主一定的自由性和效率,允许广告主在创造标题的时候以通配符的方式进行创意提交。线上服务的时候,会根据用户的搜索词触发的 bidword 对创意中的通配符(通配符是用成对 {} 括起来的字符串,可以包含 0 个或者多个字符)进行替换 ,用来提升广告投放体验。例如:“{末日血战} 上线送 SSR 英雄,三天集齐无敌阵容!”,会被替换成“帝国时代游戏下载上线送 SSR 英雄,三天集齐无敌阵容!”。给定一个含有通配符的创意和一句标题,判断这句标题是否从该创意替换生成的。
题目分析
在这个问题中,我们需要判断给定的标题是否可以通过替换一个含有通配符的创意模板生成。通配符由成对的花括号 {} 包围,可以代表任意长度的字符串,包括空字符串。
解题思路
- 构建正则表达式:首先,我们需要将创意模板转换为一个正则表达式。在这个正则表达式中,非通配符部分需要被转义,以避免特殊字符在正则表达式中的特殊含义。通配符部分
{...}被转换为.*,表示任意字符(包括无字符)。 - 匹配标题:使用构建好的正则表达式对每个标题进行全匹配测试。如果标题完全符合正则表达式,则返回
True,否则返回False。 - 输出结果:对于每个标题,输出一个
True或False,表示该标题是否可以通过替换创意模板生成。
代码解析
import re
def solution(n, template, titles):
# 初始化正则表达式模式字符串
regex_pattern = ''
i = 0
while i < len(template):
if template[i] == '{':
# 找到通配符开始,跳过开头的 '{'
i += 1
# 找到通配符结束的 '}'
while i < len(template) and template[i] != '}':
i += 1
# 将通配符转换为 '.*',表示任意字符
regex_pattern += '.*'
else:
# 非通配符字符需要被转义
regex_pattern += re.escape(template[i])
i += 1
# 构建正则表达式对象,^ 和 $ 分别表示字符串的开始和结束
regex = re.compile(f'^{regex_pattern}$')
# 使用列表推导式对每个标题进行匹配测试
results = [bool(regex.match(title)) for title in titles]
# 将结果列表转换为逗号分隔的字符串
results_str = ','.join(map(str, results))
return results_str
if __name__ == "__main__":
# 测试用例
testTitles1 = ["adcdcefdfeffe", "adcdcefdfeff", "dcdcefdfeffe", "adcdcfe"]
testTitles2 = ["CLSomGhcQNvFuzENTAMLCqxBdj", "CLSomNvFuXTASzENTAMLCqxBdj", "CLSomFuXTASzExBdj", "CLSoQNvFuMLCqxBdj", "SovFuXTASzENTAMLCq", "mGhcQNvFuXTASzENTAMLCqx"]
testTitles3 = ["abcdefg", "abefg", "efg"]
# 输出测试结果
print(solution(4, "ad{xyz}cdc{y}f{x}e", testTitles1) == "True,False,False,True")
print(solution(6, "{xxx}h{cQ}N{vF}u{XTA}S{NTA}MLCq{yyy}", testTitles2) == "False,False,False,False,False,True")
print(solution(3, "a{bdc}efg", testTitles3) == "True,True,False")
代码注释
re.escape(template[i]):将非通配符字符转义,以确保它们在正则表达式中被正确处理。regex = re.compile(f'^{regex_pattern}$'):构建一个正则表达式对象,^和$确保整个字符串必须完全匹配。[bool(regex.match(title)) for title in titles]:使用列表推导式对每个标题进行匹配测试,返回一个布尔值列表。','.join(map(str, results)):将布尔值列表转换为逗号分隔的字符串。
通过以上步骤,我们可以有效地判断每个标题是否可以通过替换创意模板生成。