前言
随着在线广告的不断发展,广告平台的灵活性和效率逐渐成为广告主的关键需求。为了提升广告效果和用户体验,许多平台允许广告主使用通配符来构建创意标题。例如,广告主可以在标题中使用花括号 通配符(通配符是用成对 {} 括起来的字符串,可以包含 0 个或者多个字符) 来定义一个可以动态替换的部分,这样可以根据用户的搜索词和投放情况自动生成个性化的标题,从而提高广告的相关性和点击率。
本篇文章将介绍如何使用编程语言(以 Java 为例)解决创意标题匹配问题,即给定一个含有通配符的创意模板和多个实际标题,判断这些标题是否是由该模板经过替换后生成的。
题目
问题分析
问题本质上是一个模式匹配问题。广告主的模板类似于带有占位符(通配符)的正则表达式,而需要匹配的标题就相当于要验证的字符串。通过将模板中的通配符部分替换成正则表达式中的匹配模式,可以使用正则表达式来验证每个标题是否匹配该模板。
输入与输出
输入:
- n:标题的数量(整数)。
- template:一个包含通配符的模板字符串,通配符用
{}括起来。 - titles:一个包含多个标题的字符串数组。
输出:
- 对于每个标题,判断它是否能够由模板生成。如果能够生成,输出
True,否则输出False。
问题的关键点
-
模板和标题的匹配关系:
- 模板中的每个
{}部分都代表一个动态的替换部分,可以匹配任意字符,因此在匹配过程中需要将其转换为正则表达式中的.*(表示任意字符)。 - 模板中的常规字符需要严格匹配。比如,模板
ad{xyz}cdc{y}f{x}e中的ad和cdc等字符必须精确匹配标题中的相应部分。
- 模板中的每个
-
正则表达式的应用:
- 模板中的
{}通配符需要转化为.*,使其能够匹配任意字符序列。 - 每个标题需要和转换后的正则表达式进行匹配,若匹配成功,则认为该标题是模板替换后的结果。
- 模板中的
-
替换规则的灵活性:
- 模板的灵活性体现在
{}部分的内容可以有多个字符,甚至为空。 - 每个
{}代表一个占位符,可以匹配任意字符串,这使得匹配的方式非常灵活,但也要求匹配时能够识别出有效的占位符替换。
- 模板的灵活性体现在
思路
1. 模板转换
首先需要将模板中的 {} 替换为正则表达式中的 .*。例如,对于模板 ad{xyz}cdc{y}f{x}e,我们可以将其转化为正则表达式 ^ad.*cdc.*f.*e$,其中:
^和$表示匹配整个字符串。.*表示任意字符(包括零个字符)。
2. 标题匹配
对每个标题,我们需要使用生成的正则表达式进行匹配。如果标题符合正则表达式,则认为它是由模板通过替换生成的。
3. 正则表达式匹配
通过正则表达式提供的 matches 方法来验证每个标题是否符合转换后的模式。如果匹配成功,输出 True;否则输出 False。
解决方案的实现步骤
- 将模板转换为正则表达式:使用
template.replaceAll("\{[^}]*}", ".*")将模板中的{}替换为.*。 - 使用正则表达式检查每个标题:通过正则表达式对象的
matcher方法对每个标题进行匹配。 - 返回匹配结果:将匹配结果转换成字符串(
True或False),并通过逗号连接所有结果。
下面是具体实现的代码(基于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"));
}
}
代码说明
- 正则表达式构建:通过
template.replaceAll("\{[^}]*}", ".*")将模板中的{}替换为.*,形成可匹配任意字符的正则表达式。 - 正则匹配:对于每个标题,使用
regex.matcher(titles[i]).matches()判断该标题是否与正则表达式匹配,若匹配则返回True,否则返回False。 - 返回结果:最终将所有结果连接成字符串形式返回。
总时间复杂度
- 模板替换和正则表达式编译:O(T)
- 标题匹配:O(n×L)
- 生成结果:O(n)
因此,整体的时间复杂度为:
O(T+n×L)
其中:
- T 是模板字符串的长度。
- n 是标题的数量。
- L 是每个标题的最大长度。
最后
本文通过结合正则表达式的应用,提出了一种高效的解决方案,能够帮助广告平台判断给定的标题是否符合模板生成的规则。通过将通配符部分转换为正则表达式,能够简洁且高效地实现标题匹配功能。随着广告平台不断增加创意生成的灵活性,这种解决方案具有重要的实际应用价值,并为开发者提供了一个通用的思路,解决类似的匹配问题。