【007】"创意标题匹配问题"深度解析 | 豆包MarsCode AI 刷题

238 阅读5分钟

前言

随着在线广告的不断发展,广告平台的灵活性和效率逐渐成为广告主的关键需求。为了提升广告效果和用户体验,许多平台允许广告主使用通配符来构建创意标题。例如,广告主可以在标题中使用花括号 通配符(通配符是用成对 {} 括起来的字符串,可以包含 0 个或者多个字符) 来定义一个可以动态替换的部分,这样可以根据用户的搜索词和投放情况自动生成个性化的标题,从而提高广告的相关性和点击率。

本篇文章将介绍如何使用编程语言(以 Java 为例)解决创意标题匹配问题,即给定一个含有通配符的创意模板和多个实际标题,判断这些标题是否是由该模板经过替换后生成的。

题目

image.png

问题分析

问题本质上是一个模式匹配问题。广告主的模板类似于带有占位符(通配符)的正则表达式,而需要匹配的标题就相当于要验证的字符串。通过将模板中的通配符部分替换成正则表达式中的匹配模式,可以使用正则表达式来验证每个标题是否匹配该模板。

输入与输出

输入:

  • n:标题的数量(整数)。
  • template:一个包含通配符的模板字符串,通配符用 {} 括起来。
  • titles:一个包含多个标题的字符串数组。

输出:

  • 对于每个标题,判断它是否能够由模板生成。如果能够生成,输出 True,否则输出 False

问题的关键点

  1. 模板和标题的匹配关系

    • 模板中的每个 {} 部分都代表一个动态的替换部分,可以匹配任意字符,因此在匹配过程中需要将其转换为正则表达式中的 .*(表示任意字符)。
    • 模板中的常规字符需要严格匹配。比如,模板 ad{xyz}cdc{y}f{x}e 中的 adcdc 等字符必须精确匹配标题中的相应部分。
  2. 正则表达式的应用

    • 模板中的 {} 通配符需要转化为 .*,使其能够匹配任意字符序列。
    • 每个标题需要和转换后的正则表达式进行匹配,若匹配成功,则认为该标题是模板替换后的结果。
  3. 替换规则的灵活性

    • 模板的灵活性体现在 {} 部分的内容可以有多个字符,甚至为空。
    • 每个 {} 代表一个占位符,可以匹配任意字符串,这使得匹配的方式非常灵活,但也要求匹配时能够识别出有效的占位符替换。

思路

1. 模板转换

首先需要将模板中的 {} 替换为正则表达式中的 .*。例如,对于模板 ad{xyz}cdc{y}f{x}e,我们可以将其转化为正则表达式 ^ad.*cdc.*f.*e$,其中:

  • ^$ 表示匹配整个字符串。
  • .* 表示任意字符(包括零个字符)。
2. 标题匹配

对每个标题,我们需要使用生成的正则表达式进行匹配。如果标题符合正则表达式,则认为它是由模板通过替换生成的。

3. 正则表达式匹配

通过正则表达式提供的 matches 方法来验证每个标题是否符合转换后的模式。如果匹配成功,输出 True;否则输出 False

解决方案的实现步骤

  1. 将模板转换为正则表达式:使用 template.replaceAll("\{[^}]*}", ".*") 将模板中的 {} 替换为 .*
  2. 使用正则表达式检查每个标题:通过正则表达式对象的 matcher 方法对每个标题进行匹配。
  3. 返回匹配结果:将匹配结果转换成字符串(TrueFalse),并通过逗号连接所有结果。

下面是具体实现的代码(基于Java)

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

public class Main {
    public static String solution(int n, String template, String[] titles) {
        // 将模板中的 "{...}" 替换为 ".*",形成正则表达式
        String regexPattern = "^" + template.replaceAll("\\{[^}]*}", ".*") + "$";
        Pattern regex = Pattern.compile(regexPattern);
        
        List<String> result = new ArrayList<>();

        // 检查每个标题是否匹配正则表达式
        for (int i = 0; i < n; i++) {
            if (regex.matcher(titles[i]).matches()) {
                result.add("True");
            } else {
                result.add("False");
            }
        }

        // 将结果列表连接成字符串并返回
        return String.join(",", result);
    }

    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. 正则匹配:对于每个标题,使用 regex.matcher(titles[i]).matches() 判断该标题是否与正则表达式匹配,若匹配则返回 True,否则返回 False
  3. 返回结果:最终将所有结果连接成字符串形式返回。

总时间复杂度

  • 模板替换和正则表达式编译:O(T)
  • 标题匹配:O(n×L)
  • 生成结果:O(n)

因此,整体的时间复杂度为:

O(T+n×L)

其中:

  • T 是模板字符串的长度。
  • n 是标题的数量。
  • L 是每个标题的最大长度。

最后

本文通过结合正则表达式的应用,提出了一种高效的解决方案,能够帮助广告平台判断给定的标题是否符合模板生成的规则。通过将通配符部分转换为正则表达式,能够简洁且高效地实现标题匹配功能。随着广告平台不断增加创意生成的灵活性,这种解决方案具有重要的实际应用价值,并为开发者提供了一个通用的思路,解决类似的匹配问题。