[python]创意标题匹配问题 | 豆包MarsCode AI刷题

77 阅读2分钟

创意标题匹配问题

题目描述

在广告平台中,广告主可以使用包含通配符的标题模板来创建广告创意,以便根据用户的搜索词动态生成不同的标题。模板中的通配符是以 {} 包裹的字符串,可能为空或包含若干字符。系统会将用户搜索词替换通配符部分,从而生成最终展示给用户的广告标题。

例如,模板为 {末日血战} 上线送 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"

题目思路

解决这个问题的关键在于匹配通配符模板与实际标题之间的模式。主要思路如下:

  1. 将通配符转为正则表达式:模板中的 {...} 代表通配符,可以用正则表达式的 .* 替代,匹配任何字符串,包括空字符串。将模板中的 {...} 替换为 .*,得到一个正则表达式。

  2. 匹配生成的正则表达式:将生成的正则表达式应用于每个标题,检查是否匹配。如果匹配,说明该标题可能是通过模板生成的。

  3. 输出匹配结果:遍历每个标题,将匹配结果存入列表中,并返回该列表的字符串表示。

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")

代码解析

  1. 正则表达式替换regex_template 使用 re.sub 将所有 {...} 替换为 .*,生成正则表达式。
  2. 匹配操作re.match 将每个标题与正则表达式 regex_template 匹配,如果匹配成功则返回 True,否则返回 False
  3. 结果输出:用 ",".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]:匹配 abc 中的任意一个字符。
  • \d:匹配任意数字字符(等价于 [0-9])。

在题目中,我们用 .* 替代 {...},因为 .* 是正则表达式中匹配任意字符的符号。