原题地址:创意标题匹配问题 - MarsCode
问题描述
在广告平台中,为了给广告主一定的自由性和效率,允许广告主在创造标题的时候以通配符的方式进行创意提交。线上服务的时候,会根据用户的搜索词触发的 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. solution方法整体功能概述
solution方法的主要功能是接收一个整数 n(在当前代码逻辑中似乎未被实际使用,可能是预留参数或者代码功能后续会扩展用到)、一个模板字符串 template_ 以及一个字符串数组 titles。它会遍历 titles 数组中的每个标题字符串,通过调用 matchesTemplate 辅助方法来判断每个标题是否能依据给定的模板生成,然后将判断结果(True 或 False)依次拼接成一个字符串,每个结果之间用逗号分隔,最后返回这个拼接好的字符串(需要注意会去除最后多余的逗号)。
2. solution方法代码步骤解析
步骤一:初始化结果字符串
收起
java
复制
StringBuilder result = new StringBuilder();
创建了一个 StringBuilder 对象 result,用于高效地拼接后续要生成的包含每个标题匹配结果的字符串。使用 StringBuilder 而不是直接用普通字符串拼接(如 + 操作符),可以避免频繁创建新的字符串对象,提高性能,尤其是在大量字符串拼接的场景下。
步骤二:遍历每个标题
收起
java
复制
for (String title : titles) {
if (matchesTemplate(template_, title)) {
result.append("True,");
} else {
result.append("False,");
}
}
通过增强 for 循环遍历输入的 titles 数组中的每一个标题字符串。对于每个标题,调用 matchesTemplate 辅助方法来判断该标题是否与给定的模板 template_ 相匹配。如果匹配成功,就向 result 中追加字符串 "True,";如果匹配失败,则追加 "False,",这样每个标题的判断结果都会依次添加到 result 字符串中,并且以逗号进行分隔。
步骤三:移除最后一个多余的逗号
收起
java
复制
if (result.length() > 0) {
result.setLength(result.length() - 1);
}
由于在前面的循环中每次添加结果都会带上逗号,所以最后一个结果后面的逗号是多余的。通过判断 result 的长度是否大于 0(避免空字符串情况),然后使用 setLength 方法将 result 的长度减 1,从而实现移除最后一个多余逗号的操作,使得最终返回的字符串格式符合要求。
步骤四:返回结果字符串
收起
java
复制
return result.toString();
将 StringBuilder 对象 result 转换为普通字符串并返回,这个字符串包含了所有标题与模板匹配情况的结果,以逗号分隔(除最后一个结果后无逗号)。
3. matchesTemplate辅助方法代码解析
步骤一:将模板中的通配符替换为正则表达式中的通配符
收起
java
复制
String regex = template.replaceAll("\{[^}]*\}", ".*");
这行代码的目的是把模板字符串 template 里类似 {} 形式的通配符替换为正则表达式中的通配符 .*(在正则表达式中,.* 表示匹配任意字符零次或多次)。这样做是为了后续能够利用正则表达式的匹配机制来判断标题是否符合模板要求。例如,如果模板是 "article-{id}-{name}",经过这一步替换后就会变成 "article-.*-.*",方便后续进行更通用的匹配判断。
步骤二:编译正则表达式
收起
java
复制
Pattern pattern = Pattern.compile(regex);
使用 Pattern 类的 compile 方法将上一步得到的正则表达式字符串 regex 编译成一个 Pattern 对象,编译后的 Pattern 对象可以用于创建 Matcher 对象来执行具体的匹配操作,这是 Java 中使用正则表达式进行文本匹配的标准步骤之一。
步骤三:匹配标题
收起
java
复制
Matcher matcher = pattern.matcher(title);
通过已经编译好的 Pattern 对象 pattern 创建一个 Matcher 对象 matcher,并传入要匹配的标题字符串 title。这个 Matcher 对象提供了各种方法来执行匹配操作并获取匹配相关的信息。
步骤四:返回匹配结果
收起
java
复制
return matcher.matches();
调用 Matcher 对象的 matches 方法,该方法会尝试将整个输入的标题字符串与编译好的正则表达式进行匹配,如果完全匹配成功(即标题字符串从头到尾符合正则表达式所定义的模式),则返回 true,表示标题可以从模板生成;否则返回 false,表示标题不符合模板要求。然后将这个匹配结果返回给调用它的 solution 方法,供其判断并记录每个标题的匹配情况。