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

110 阅读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"

解题思路

这是一个关于字符串匹配和通配符处理的问题。核心思路是对给定的含有通配符的创意模板与每个标题进行比较,检查标题是否能通过创意模板中的通配符替换得到。

  1. 通配符处理

    • 通配符用成对的{}表示,可以包含任意字符。在比较过程中,需要跳过通配符部分进行字符的匹配。
  2. 逐个比较

    • 对于每个标题,按照从左到右的顺序与创意模板进行比较。当遇到创意模板中的通配符时,在标题中对应的位置应该有相应的字符序列(可能为空),并且后续的非通配符字符也应该匹配。

步骤分析

  1. 解析创意模板

    • 首先,需要对创意模板进行解析,标记出通配符的位置和内容。可以通过遍历创意模板字符串,当遇到{时,记录通配符开始位置,当遇到}时,记录通配符结束位置,从而确定通配符部分。
  2. 标题比较

    • 对于每个标题,设置两个指针,一个指向创意模板,一个指向标题。
    • 当创意模板指针指向非通配符字符时,比较创意模板和标题中对应位置的字符是否相同。如果不同,则该标题不符合要求。
    • 当创意模板指针指向通配符时,在标题中跳过相应长度的字符(通配符内的字符长度可以为0),然后继续比较后续的字符。
  3. 结果记录

    • 根据每个标题与创意模板的比较结果,生成相应的布尔值结果,最后将这些布尔值转换为题目要求的字符串形式(TrueFalse连接成的字符串)。

代码实现

以下是基于上述思路的C++实现代码:

#include <iostream>
#include <string> 
#include <vector> 
std::string check_titles(int n, const std::string& templateStr, const std::vector<std::string>& titles) { 
    std::vector<std::string> results; 
    for (const auto& title : titles) { 
        int template_ptr = 0; 
        int title_ptr = 0; 
        while (template_ptr < templateStr.length() && title_ptr < title.length()) { 
            if (templateStr[template_ptr] == '{') { 
                int end = templateStr.find('}', template_ptr); 
                template_ptr = end + 1; } 
                else if (templateStr[template_ptr]!= title[title_ptr]) { 
                    break; 
                } else 
                { template_ptr++; title_ptr++; 
                }
            } 
            if (template_ptr == templateStr.length() && title_ptr == title.length()) {                   results.push_back("True"); 
            } else { 
                results.push_back("False"); 
            } 
        } 
        std::string resultStr = ""; 
        for (size_t i = 0; i < results.size(); i++) { 
            if (i!= 0) { 
                resultStr += ","; 
                } 
            resultStr += results[i]; 
        } 
     return resultStr; 
 }
  1. 函数定义与参数接收

    • 定义函数check_titles,它接受一个整数n(与题目输入格式一致,在函数内部未实际用于计算)、一个常量引用的字符串templateStr(创意模板)和一个常量引用的字符串向量titles(标题列表)。
  2. 结果向量初始化与标题遍历

    • 创建一个空的字符串向量results来存储每个标题的比较结果。
    • 使用范围for循环遍历titles中的每个标题。对于每个标题,初始化两个指针template_ptrtitle_ptr,分别用于指向创意模板和标题的当前字符位置。
  3. 比较逻辑

    • while循环中,只要template_ptr小于创意模板的长度并且title_ptr小于标题的长度,就进行比较。

      • 如果创意模板的当前字符是{,则找到对应的}的位置,并将template_ptr移动到}之后的位置。
      • 如果创意模板的当前字符与标题的当前字符不相同,则跳出while循环。
      • 如果相同,则将两个指针都向后移动一位。
  4. 结果判断与添加到结果向量

    • while循环结束后,如果template_ptr等于创意模板的长度并且title_ptr等于标题的长度,说明标题符合要求,将"True"添加到results向量中;否则,将"False"添加到results向量中。
  5. 构建最终结果字符串

    • 创建一个空字符串resultStr,然后遍历results向量。对于每个元素,如果不是第一个元素,则在前面添加一个逗号,然后将元素添加到resultStr中。
  6. 结果返回

    • 最后,返回构建好的resultStr,它包含了所有标题的比较结果字符串。

时间复杂度和空间复杂度

  1. 时间复杂度

    • 对于每个标题,在最坏情况下,需要遍历创意模板和标题的每个字符。假设创意模板的长度为m,标题的平均长度为k,总共有n个标题。那么时间复杂度为O(n∗(m+k))O(n∗(m+k))
  2. 空间复杂度

    • 除了结果列表results,没有使用额外的与输入规模相关的空间。结果列表的长度取决于标题的数量n,所以空间复杂度为O(n)O(n)

总结

通过对创意模板和标题的仔细分析与比较,我们可以有效地判断标题是否是从创意模板通过通配符替换得到的。这种方法在广告平台中对于准确投放广告、提升广告投放体验有着重要的意义。