简单题:创意标题匹配 | 豆包MarsCode AI刷题

138 阅读5分钟

问题描述

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

测试样例

样例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"`

解题思路

错误思路

在一开始我是用用ai给了我一些解题思路来和我自己的思路进行比较,发现和我的大致思路差不多,然后我就用它给出来的代码敲了一遍,如下所示:

def solution(n, template_, titles):
    results = []  # 初始化结果列表
    
    for title in titles:  # 遍历每个标题
        i, j = 0, 0  # 初始化指针
        match = True  # 初始化匹配标志
        
        while i < len(template_) and j < len(title):
            if template_[i] == '{':
                # 跳过通配符内容
                while i < len(template_) and template_[i] != '}':
                    i += 1
                i += 1  # 移动到通配符后的字符
            else:
                if template_[i] != title[j]:
                    match = False
                    break
                i += 1
                j += 1
        
        # 检查是否完全匹配
        if match and i == len(template_) and j == len(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. 解析模板:提取模板中固定的部分
  2. 检查占位符:判断模板是否以占位符开头或结尾
  3. 匹配标题:根据固定部分和占位符的情况,匹配标题字符串(如果模板的开头没有占位符,确保第一个固定部分匹配标题的开头;如果结尾没有占位符,要确保最后一个固定部分匹配标题的结尾;其他固定部分只需按顺序匹配即可)

详细实现

def parse_template(template):
    fixed_parts = []
    i = 0
    while i < len(template):
        if template[i] == '{':
            while i < len(template) and template[i] != '}':
                i += 1
            i += 1  # 跳过右“}”
        else:
            start = i
            while i < len(template) and template[i] != '{':
                i += 1
            fixed_parts.append(template[start:i])
    return fixed_parts

def has_leading_placeholder(template):
    return template.startswith('{')

def has_trailing_placeholder(template):
    return template.endswith('}')

def match_title(fixed_parts, title, leading_placeholder, trailing_placeholder):
    start = 0
	# 从哪一位开始,匹配后就前面的就不管了
    for index, part in enumerate(fixed_parts):
        if index == 0 and not leading_placeholder:
            # 保证开头没有自由替换的部分时匹配的字符串第一个部分也在开头
            pos = title.find(part, start)
            if pos != 0:
                return False
            start = pos + len(part)
        elif index == len(fixed_parts) - 1 and not trailing_placeholder:
            # 保证结尾没有自由替换的部分时匹配的字符串第一个部分也在结尾
            pos = title.rfind(part, start)
            # 找最后一个
            if pos == -1 or pos + len(part) != len(title):
                return False
        else:
            pos = title.find(part, start)
            if pos == -1:
                return False
            start = pos + len(part)
    return True

def solution(n, template, titles):
    fixed_parts = parse_template(template)
    leading_placeholder = has_leading_placeholder(template)
    trailing_placeholder = has_trailing_placeholder(template)
    results = []
    for title in titles:
        if match_title(fixed_parts, title, leading_placeholder, trailing_placeholder):
            results.append("True")
        else:
            results.append("False")
    return ",".join(results)



if __name__ == "__main__":
    #  You can add more test cases here
    testTitles1 = ["adcdcefdfeffe", "adcdcefdfeff", "dcdcefdfeffe", "adcdcfe"]
    testTitles2 = ["abcdefg", "abefg", "efg"]
    testTitles3 = ["xyzdef", "abcdef","abxyzdef", "xyz", "abxyz"]

    print(solution(4, "ad{xyz}cdc{y}f{x}e", testTitles1))
    print(solution(3, "a{bdc}efg", testTitles2))
    print(solution(5,"{abc}xyz{def}", testTitles3))

代码解释

  1. 首先定义parse_template函数来提取模板中固定的部分。如果遇到template[i]=="{",就一直循环,直到"}",如果遇到的是固定的部分,就在原来的基础上(start = i)再次循环,循环至遇到"{"截止,然后把循环的这一部分所遍历的字符串添加到创建的fix_parts列表中。
  2. 定义两个函数来检查占位符,用于后续操作。
  3. 匹配标题。首先for循环模板中的固定的部分,然后再进行讨论。
  4. 主函数。

心得体会

感觉这个题目对我这个小白来说是有一点难度的,解题思路方法很重要。