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

267 阅读3分钟

1.创意标题匹配问题

问题描述

在广告平台中,为了给广告主一定的自由性和效率,允许广告主在创造标题的时候以通配符的方式进行创意提交。线上服务的时候,会根据用户的搜索词触发的 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"

2.解题思路

这个问题的核心在于如何将包含 {} 的模板转化为可以用于正则表达式匹配的形式,并检查每个标题是否符合这个模板。

分析

  1. 模板转化为正则表达式:

    {} 是一个通配符,代表一个可以匹配零个或多个字符。因此,我们需要将模板中的每个 {} 替换为正则表达式中的 .*,这可以匹配任意长度的字符。

    需要注意的是,{} 可能包含字母、数字或者其他字符,所有这些字符都应该视作正常字符而不是正则表达式的特殊字符,所以我们需要正确处理这些内容。

  2. 正则表达式的构造:

    在模板中,{} 可以包裹任意字符,因此,{} 之间的内容都可以通过 .* 来表示。

    完整的正则表达式需要以 ^ 开头和 $ 结尾,这样可以确保整个字符串与模板严格匹配。

  3. 匹配过程:

    通过构造正则表达式后,我们就可以使用正则表达式匹配每个标题。

    对于每个标题,如果能够完全匹配正则表达式,说明这个标题符合模板,返回 True;否则,返回 False

步骤

  1. 将模板转换为正则表达式:

    替换所有的 {}.*

    添加正则表达式的开始和结束符号 ^$,保证匹配的是完整字符串。

  2. 匹配标题:

    对于每一个标题,使用转换后的正则表达式进行匹配。

  3. 输出结果:

    对每个标题,输出 TrueFalse,并按逗号分隔。

3.代码实现

import java.util.regex.*;

public class Main {
    public static String solution(int n, String template_, String[] titles) {
        // 替换模板中的通配符为正则表达式
        String regex = template_.replaceAll("\\{[^}]*\\}", ".*");
        // 加上开始和结束标记
        regex = "^" + regex + "$";

        Pattern pattern = Pattern.compile(regex);
        StringBuilder result = new StringBuilder();

        for (int i = 0; i < n; i++) {
            Matcher matcher = pattern.matcher(titles[i]);
            if (matcher.matches()) {
                result.append("Tarue");
            } else {
                result.append("False");
            }
            if (i < n - 1) {
                result.append(",");
            }
        }

        return result.toString();
    }

    public static void main(String[] args) {
        String[] testTitles1 = {"adcdcefdfeffe", "adcdcefdfeff", "dcdcefdfeffe", "adcdcfe"};
        String[] testTitles2 = {"CLSomGhcQNvFuzENTAMLCqxBdj", "CLSomNvFuXTASzENTAMLCqxBdj", "CLSomFuXTASzExBdj", "CLSoQNvFuMLCqxBdj", "SovFuXTASzENTAMLCq", "mGhcQNvFuXTASzENTAMLCqx"};
        String[] testTitles3 = {"abcdefg", "abefg", "efg"};

        System.out.println(solution(4, "ad{xyz}cdc{y}f{x}e", testTitles1).equals("True,False,False,True"));
        System.out.println(solution(6, "{xxx}h{cQ}N{vF}u{XTA}S{NTA}MLCq{yyy}", testTitles2).equals("False,False,False,False,False,True"));
        System.out.println(solution(3, "a{bdc}efg", testTitles3).equals("True,True,False"));
    }
}

  1. template_ 的处理

    • 使用 replaceAll("\{[^}]*\}", ".*") 将模板中的所有 {} 转换为 .*[^}]* 用于匹配 {} 内的所有字符,包括字母、数字和特殊字符。
    • ^$ 用于确保整个字符串从头到尾完全匹配。
  2. 匹配过程

    • 使用 Pattern.compile(regex) 将转换后的正则表达式编译成 Pattern 对象。
    • 使用 matcher.matches() 来检查每个标题是否完全匹配正则表达式。
  3. 结果构建

    • 将每个匹配结果(TrueFalse)拼接到 StringBuilder 中,多个结果之间用逗号分隔。

4.时间复杂度

  • 时间复杂度:每个标题进行一次正则匹配,匹配的时间复杂度为 O(m),其中 m 是标题的长度。对于 n 个标题,总时间复杂度是 O(n * m)。
  • 空间复杂度:主要是用来存储正则表达式和结果的空间,空间复杂度为 O(n),其中 n 是标题的数量。