创意标题匹配问题 问题描述 在广告平台中,为了给广告主一定的自由性和效率,允许广告主在创造标题的时候以通配符的方式进行创意提交。线上服务的时候,会根据用户的搜索词触发的 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"
以下是对该问题的详细分析:
一、问题理解
我们面临的任务是在广告平台的情境下,给定一个带有通配符(用成对 {} 括起来的字符串)的创意内容,以及若干个标题。需要判断这些给定的标题是否是通过将创意中的通配符按照特定规则替换后生成的。本质上是要对比创意和标题之间的内容关系,找出符合通配符替换逻辑的匹配情况。
二、关键要素分析
- 通配符特征:通配符是用成对 {} 括起来的字符串,可以包含 0 个或者多个字符。这意味着通配符在创意中是作为可替换部分存在的,其内部的字符情况不确定,可能为空,也可能是各种字符组合。
- 替换逻辑:线上服务时会根据用户搜索词触发的 bidword 对创意中的通配符进行替换。这说明替换是基于一定的触发条件(用户搜索词及对应的 bidword)来实现的,且替换后的结果应该能与给定的标题在内容上完全匹配(除了通配符被替换的部分)。
三、判断思路
- 提取通配符内容:首先需要从给定的含有通配符的创意中准确识别出通配符部分,即找到所有用 {} 括起来的字符串。可以通过字符串匹配的方式,按照 {} 的起始和结束标记来定位通配符。
- 对比创意与标题:将提取出通配符后的创意剩余部分与给定的标题进行初步对比。如果这部分内容不相等,那么该标题肯定不是由该创意替换生成的,可以直接排除。
- 处理通配符替换情况:对于通过初步对比的情况,接下来要分析标题中与创意通配符位置对应的部分。检查这些部分是否符合通配符可能的替换规则,即是否是根据某种 bidword 进行了合理替换,使得整体内容与创意经过替换后能完全匹配。这可能需要考虑一些细节,比如通配符替换后的字符长度、字符类型等是否合理。
四、可能遇到的挑战及解决方法
- 通配符嵌套问题:有可能出现通配符内部又包含通配符的情况,如 {{嵌套通配符}}。在提取通配符时,需要设计合适的算法来正确处理这种嵌套结构,比如可以采用递归的方式,先处理最内层的通配符,再逐步向外处理。
- 模糊匹配情况:有时候可能存在部分相似但不完全准确的替换情况,比如通配符替换后的内容在语义上相近但字符不完全一致。这可能需要引入一些自然语言处理的技术,如词汇相似度计算、语义理解等,来更准确地判断是否符合替换生成的要求。不过如果是严格按照字符匹配的要求来判断是否由创意替换生成,那么这种语义相近但字符不同的情况通常应判定为不符合。
五、整体流程总结
-
从给定创意中提取通配符内容。
-
对比提取通配符后的创意剩余部分与给定标题,排除明显不匹配的标题。
-
对于剩余可能匹配的标题,分析其与创意通配符位置对应的部分,判断是否符合通配符替换规则,考虑处理可能遇到的通配符嵌套等问题。
通过以上分析可知,要判断一个标题是否从给定的含有通配符的创意替换生成的,需要仔细分析通配符的特征、替换逻辑,按照一定的流程和方法进行对比和判断,并妥善处理可能出现的各种复杂情况。
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) {
// n个测试样例,template 通配符,titles模板
// 思路:① 记录通配符,② 匹配
// 将模板转换为正则表达式,并确保匹配整个字符串
String regex = template.replaceAll("\\{[^}]*}",".*");
regex = "^" + regex + "$";
// 创建一个 StringBuilder 来存储结果
StringBuilder result = new StringBuilder();
// 遍历每个标题。若匹配成功,添加true;失败则添加false
for(String title: titles) {
result.append( Pattern.matches(regex,title) ? "True" : "False").append(",");
}
// 删除最后一个逗号
if(result.length() > 0) {
result.deleteCharAt(result.length()-1);
}
return result.toString();
}
public static void main(String[] args) {
// You can add more test cases here
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"));
}
}