青训营X豆包MarsCode 技术训练营第二课:创意标题匹配问题算法解析 | 豆包MarsCode AI 刷题

138 阅读5分钟

题目分析

给定两个字符串:一个是广告创意(包含通配符),另一个是实际广告标题。我们需要判断广告标题是否能够从创意通过替换通配符的方式生成。通配符的替换规则如下:

  • {} 中的内容可以被替换为任意字符(包括空字符)。
  • {} 中的内容不限制字符的数量。

任务: 我们需要检查标题是否可以通过在创意中替换通配符生成。例如,如果创意是:“{末日血战} 上线送 SSR 英雄,三天集齐无敌阵容!”,标题是:“帝国时代游戏下载上线送 SSR 英雄,三天集齐无敌阵容!”,那么标题中的 {末日血战} 部分可以被替换为“帝国时代游戏下载”,符合题意。

解题思路

  1. 解析创意字符串: 创意字符串中包含了 {} 形式的通配符,我们需要将它们提取出来,然后将创意分成多个段落(包括普通文本和通配符段)。

  2. 逐段匹配

    • 对于每个普通文本段,我们需要检查广告标题中的相应部分是否完全匹配。
    • 对于每个通配符段,我们只需匹配标题中该部分是否能够覆盖通配符,即允许任意字符。
  3. 边界处理

    • 如果创意中的第一个段落是通配符(即创意从 {} 开始),我们需要检查标题的开头是否可以匹配。
    • 如果创意中的最后一个段落是通配符(即创意以 {} 结束),我们需要检查标题的结尾是否可以匹配。
  4. 算法步骤

    • 将创意字符串按 {} 分割为多个段落,生成一个段落列表。
    • 对照广告标题,逐段检查是否匹配。如果遇到通配符段,则可以跳过或使用任意字符匹配;否则,必须严格匹配对应的段落。
  5. 边界情况

    • 广告创意中没有 {},即创意是固定的字符串,需要完全匹配。
    • 广告标题为空,创意中有 {} 的部分应可以匹配任何内容。

示例

创意"帝国时代游戏下载{末日血战}上线送 SSR 英雄,三天集齐无敌阵容!" 标题"帝国时代游戏下载上线送 SSR 英雄,三天集齐无敌阵容!"

可以看到,{末日血战} 这一部分在标题中被替换为“上线”,因此标题是创意通过替换通配符生成的。

代码实现

pythonCopy Code
import re

def is_valid_ad_title(creative, title):
    # 正则表达式将创意中的 `{}` 拆分
    pattern = re.compile(r'{(.*?)}')
    
    # 分割创意
    segments = pattern.split(creative)
    # 分割标题
    title_segments = pattern.split(title)

    # 如果创意中的通配符个数与标题中相应的通配符个数不匹配,则不合法
    if len(segments) != len(title_segments):
        return False

    # 遍历每个分割段
    for i in range(len(segments)):
        # 如果当前段是普通文本
        if i % 2 == 0:
            if segments[i] != title_segments[i]:
                return False
        # 如果当前段是通配符部分
        else:
            # 通配符可以匹配任何字符,所以直接跳过检查
            continue

    return True

# 测试案例
creative = "帝国时代游戏下载{末日血战}上线送 SSR 英雄,三天集齐无敌阵容!"
title = "帝国时代游戏下载上线送 SSR 英雄,三天集齐无敌阵容!"
print(is_valid_ad_title(creative, title))  # 输出 True

creative = "暴雪游戏{末日血战}上线送SSR 英雄,三天集齐无敌阵容!"
title = "暴雪游戏魔兽世界上线送SSR 英雄,三天集齐无敌阵容!"
print(is_valid_ad_title(creative, title))  # 输出 True

creative = "{末日血战}上线送 SSR 英雄,三天集齐无敌阵容!"
title = "帝国时代游戏下载上线送 SSR 英雄,三天集齐无敌阵容!"
print(is_valid_ad_title(creative, title))  # 输出 True

creative = "末日血战上线送 SSR 英雄,三天集齐无敌阵容!"
title = "帝国时代游戏下载上线送 SSR 英雄,三天集齐无敌阵容!"
print(is_valid_ad_title(creative, title))  # 输出 False

代码解析

  1. 正则拆分创意和标题:使用正则表达式 r'{(.*?)}' 来拆分创意和标题,将通配符部分提取出来,分别形成两个列表:segmentstitle_segments。其中,segments 保存了创意字符串中非通配符的部分,title_segments 保存了标题中的非通配符部分。

  2. 逐段比较

    • 对于每一个普通文本段(segments[i]),需要与标题中的对应段(title_segments[i])完全匹配。
    • 对于每一个通配符段(segments[i] 和 title_segments[i]),我们无需进行匹配检查,因为通配符可以匹配任何内容。
  3. 返回结果:如果所有段落都匹配成功,返回 True,否则返回 False

时间复杂度

  • 正则表达式拆分创意字符串和标题字符串的时间复杂度是 O(n),其中 n 是创意或标题字符串的长度。
  • 逐段比较的时间复杂度是 O(m),其中 m 是通配符部分的数量。总体的时间复杂度为 O(n + m),通常情况下,m 是比较小的,因此总时间复杂度大约为 O(n)。

结论

这个问题的核心是利用正则表达式来拆分创意和标题,将它们按普通文本和通配符部分进行分割和比较。通配符的处理相对简单,只要能匹配任意字符即可。