创意标题匹配问题
题目描述
在广告平台中,广告主可以使用包含通配符的标题模板来创建广告创意,以便根据用户的搜索词动态生成不同的标题。模板中的通配符是以 {} 包裹的字符串,可能为空或包含若干字符。系统会将用户搜索词替换通配符部分,从而生成最终展示给用户的广告标题。
例如,模板为 {末日血战} 上线送 SSR 英雄,三天集齐无敌阵容!,如果用户的搜索词是“帝国时代游戏下载”,则生成的标题可能是“帝国时代游戏下载上线送 SSR 英雄,三天集齐无敌阵容!”
题目要求判断给定的标题是否可能从模板生成。
示例输入
-
示例 1:
- 输入:
n = 4, template = "ad{xyz}cdc{y}f{x}e", titles = ["adcdcefdfeffe", "adcdcefdfeff", "dcdcefdfeffe", "adcdcfe"] - 输出:
"True,False,False,True"
- 输入:
-
示例 2:
- 输入:
n = 3, template = "a{bdc}efg", titles = ["abcdefg", "abefg", "efg"] - 输出:
"True,True,False"
- 输入:
-
示例 3:
- 输入:
n = 5, template = "{abc}xyz{def}", titles = ["xyzdef", "abcdef", "abxyzdef", "xyz", "abxyz"] - 输出:
"True,False,True,True,True"
- 输入:
题目思路
解决这个问题的关键在于匹配通配符模板与实际标题之间的模式。主要思路如下:
-
将通配符转为正则表达式:模板中的
{...}代表通配符,可以用正则表达式的.*替代,匹配任何字符串,包括空字符串。将模板中的{...}替换为.*,得到一个正则表达式。 -
匹配生成的正则表达式:将生成的正则表达式应用于每个标题,检查是否匹配。如果匹配,说明该标题可能是通过模板生成的。
-
输出匹配结果:遍历每个标题,将匹配结果存入列表中,并返回该列表的字符串表示。
Python 解法
下面是代码实现,使用正则表达式将通配符模板替换并匹配标题:
import re
def solution(n, template_, titles):
# 将模板中的 `{}` 替换为正则表达式的 `.*`
regex_template = "^" + re.sub(r"\{.*?\}", ".*", template_) + "$"
results = []
# 检查每个标题是否匹配生成的正则表达式
for title in titles:
if re.match(regex_template, title):
results.append("True")
else:
results.append("False")
return ",".join(results)
# 测试示例
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")
代码解析
- 正则表达式替换:
regex_template使用re.sub将所有{...}替换为.*,生成正则表达式。 - 匹配操作:
re.match将每个标题与正则表达式regex_template匹配,如果匹配成功则返回True,否则返回False。 - 结果输出:用
",".join(results)拼接结果字符串。
复杂度分析
- 时间复杂度:假设模板长度为
m,标题总数为n,每个标题的平均长度为l,则正则表达式替换和匹配的复杂度为O(n * l)。 - 空间复杂度:代码使用了额外的存储空间存放结果列表,复杂度为
O(n)。
知识点总结
1. 通配符与正则表达式的区别
在编程中,通配符和正则表达式常被用来进行字符串匹配,但二者有一些区别:
- 通配符:通常用于文件匹配(如
*.txt匹配所有文本文件)。常见的符号是*(匹配零个或多个字符)和?(匹配单个字符)。 - 正则表达式:用于复杂的模式匹配,支持更灵活的操作,如字符范围、数量限定、分组、前后匹配等,适用于更精细的匹配需求。
本题目中的 {...} 形式虽然表现为通配符,但我们使用正则表达式中的 .* 来替换,以便匹配任意内容。
2. Python 正则表达式模块 re
Python 提供了 re 模块来处理正则表达式,常用的函数包括:
re.sub(pattern, replacement, string):将字符串中符合pattern的部分替换为replacement,如在本题中用来将{...}替换为.*。re.match(pattern, string):检查字符串开头是否符合pattern,在本题用于判断标题是否符合模板。re.search(pattern, string):在整个字符串中查找是否有符合pattern的部分。re.findall(pattern, string):返回字符串中所有符合pattern的匹配项。
3. 常用正则表达式符号
为了处理各种字符串匹配任务,理解以下基本正则符号和使用场景十分重要:
.:匹配任意单个字符(不包括换行)。*:匹配前面的字符零次或多次。+:匹配前面的字符一次或多次。^:匹配字符串开头。$:匹配字符串结尾。[abc]:匹配a、b或c中的任意一个字符。\d:匹配任意数字字符(等价于[0-9])。
在题目中,我们用 .* 替代 {...},因为 .* 是正则表达式中匹配任意字符的符号。