一,题目详情

1,问题描述

在广告平台中,为了给广告主一定的自由性和效率,允许广告主在创造标题的时候以通配符的方式进行创意提交。线上服务的时候,会根据用户的搜索词触发的 bidword 对创意中的通配符(通配符是用成对 {} 括起来的字符串,可以包含 0 个或者多个字符)进行替换,用来提升广告投放体验。例如:“{末日血战} 上线送 SSR 英雄,三天集齐无敌阵容!”,会被替换成“帝国时代游戏下载上线送 SSR 英雄,三天集齐无敌阵容!”。给定一个含有通配符的创意和n个标题,判断这句标题是否从该创意替换生成的。


2,测试样例

样例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 解题 - 创意标题匹配问题_bc

二、解题思路

1. 问题分析

我们需要判断给定的标题是否是由模板中的通配符替换生成的。模板中的通配符是用成对的 {} 括起来的字符串,可以匹配任意长度的字符(包括空字符串)。我们需要将模板转换为正则表达式模式,然后使用正则表达式匹配每个标题。

2. 详细分析
  1. 模板转换
  • 将模板中的通配符 {...} 替换为正则表达式的匹配模式 (.*?),表示匹配任意长度的字符。
  • 普通字符需要转义,以确保它们在正则表达式中被正确匹配。
  1. 正则表达式匹配
  • 使用 re.fullmatch 函数来判断每个标题是否完全匹配转换后的正则表达式模式。

三、代码实现

import re

def solution(n, template_, titles):
    # 将模板里的通配符替换为匹配的正则表达式
    regex_pattern = "^"  # 开始匹配
    i = 0
    while i < len(template_):
        if template_[i] == '{':
            # 找到通配符的开始
            j = i
            while j < len(template_) and template_[j] != '}':
                j += 1
            # 提取通配符并跳过它
            if j < len(template_):
                regex_pattern += "(.*?)"  # 通配符匹配任意字符
                i = j + 1
            else:
                raise ValueError("Malformed template: unbalanced '{'.")
        else:
            # 普通字符的匹配
            regex_pattern += re.escape(template_[i])  # 转义特殊字符
            i += 1
    regex_pattern += "$"  # 结束匹配
    
    # 结果判定
    result = []
    for title in titles:
        if re.fullmatch(regex_pattern, title):
            result.append("True")
        else:
            result.append("False")
    
    return ",".join(result)

if __name__ == "__main__":
    # 测试样例
    print(solution(4, "ad{xyz}cdc{y}f{x}e", ["adcdcefdfeffe", "adcdcefdfeff", "dcdcefdfeffe", "adcdcfe"]))  # "True,False,False,True"
    print(solution(3, "a{bdc}efg", ["abcdefg", "abefg", "efg"]))  # "True,True,False"
    print(solution(5, "{abc}xyz{def}", ["xyzdef", "abcdef", "abxyzdef", "xyz", "abxyz"]))  # "True,False,True,True,True"
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.

四、逐步推演(以样例1为例)

输入:

n = 4
template = "ad{xyz}cdc{y}f{x}e"
titles = ["adcdcefdfeffe", "adcdcefdfeff", "dcdcefdfeffe", "adcdcfe"]
  • 1.
  • 2.
  • 3.

推演过程如下:

步骤

操作

结果

1

转换模板为正则表达式模式

^ad(.*?)cdc(.*?)f(.*?)e$

2

匹配第一个标题 "adcdcefdfeffe"

完全匹配,结果为 True

3

匹配第二个标题 "adcdcefdfeff"

不匹配,结果为 False

4

匹配第三个标题 "dcdcefdfeffe"

不匹配,结果为 False

5

匹配第四个标题 "adcdcfe"

完全匹配,结果为 True

最终结果为 "True,False,False,True",与预期一致。


五、复杂度分析

  1. 时间复杂度:O(n)
  • 转换模板为正则表达式模式的时间复杂度为 O(m),其中 m 是模板的长度。
  • 每个标题的匹配时间复杂度为 O(k),其中 k 是标题的长度。
  • 总体时间复杂度为 O(n \* k + m)。
  1. 空间复杂度:O(1)
  • 仅使用常数级额外空间。

六、总结

通过将模板转换为正则表达式模式并使用正则表达式匹配,我们实现了一个高效且简洁的解决方案。该算法具有以下特点:

  1. 高效性:时间复杂度为 O(n \* k + m),适用于大多数场景。
  2. 鲁棒性:能够处理多种输入情况,包括复杂的通配符匹配。
  3. 易读性:代码逻辑清晰,易于理解和维护。

这种解法不仅适用于本题,还可以广泛应用于类似的字符串匹配问题中。

使用 Python 解题 - 创意标题匹配问题_正则表达式_02