问题描述
在广告平台中,为了给广告主一定的自由性和效率,允许广告主在创造标题的时候以通配符的方式进行创意提交。线上服务的时候,会根据用户的搜索词触发的 bidword 对创意中的通配符(通配符是用成对 {} 括起来的字符串,可以包含 0 个或者多个字符)进行替换 ,用来提升广告投放体验。例如:“{末日血战} 上线送 SSR 英雄,三天集齐无敌阵容!”,会被替换成“帝国时代游戏下载上线送 SSR 英雄,三天集齐无敌阵容!”。给定一个含有通配符的创意和一句标题,判断这句标题是否从该创意替换生成的。
思路
- 解析模板:找出固定的部分
- 检查占位符:判断占位符是否出现在开头或结尾
- 匹配标题:根据固定部分和占位符的情况,匹配标题字符串。
代码
func solution(n int, template string, titles []string) string {
// Please write your code here
fixed_parts := parse_template(template)
head := has_head(template)
tail := has_tail(template)
var res []string = make([]string, 0)
for _, title := range titles {
//fmt.Println()
if match_title(fixed_parts, title, head, tail) {
res = append(res, "True")
} else {
res = append(res, "Fales")
}
}
//fmt.Println(fixed_parts)
//fmt.Println(strings.Join(res, ","))
return strings.Join(res, ",")
}
func parse_template(template string) []string {
var fixed_part []string = make([]string, 0)
for i := 0; i < len(template); {
if template[i] == '{' {
for i < len(template) && template[i] != '}' {
i++
}
i++
} else {
start := i
for i < len(template) && template[i] != '{' {
i++
}
fixed_part = append(fixed_part, template[start:i])
}
}
return fixed_part
}
// 判断开头是否有模板
func has_head(template string) bool {
if template[0] == '{' {
return true
}
return false
}
// 判断末尾是否有模板
func has_tail(template string) bool {
if template[len(template)-1] == '}' {
return true
}
return false
}
// target 要查找的字符串, title 源字符串, start 开始查找的位置
// 查找target在title中第一次出现的位置,返回位置
func find(target, title string, start int) int {
t := title[start:]
//fmt.Println(t)
pos := strings.Index(t, target)
//fmt.Println("in pos = ", pos)
if pos == -1 {
return -1
}
pos = start + pos
return pos
}
// target 要查找的字符串, title 源字符串, start 开始查找的位置
// 查找target在title中最后一次出现的位置,返回位置
func lastfind(target, title string, start int) int {
t := title[start:]
//fmt.Println(t)
pos := strings.LastIndex(t, target)
if pos == -1 {
return -1
}
//fmt.Println("in pos = ", pos)
pos = start + pos
return pos
}
// 匹配每个字符串
func match_title(fixed_parts []string, title string, head, tail bool) bool {
start := 0
// fmt.Println(start)
for i, v := range fixed_parts {
// 匹配第一个固定部分,先判断开头是否是模板
if i == 0 && !head {
pos := find(v, title, start)
//fmt.Println("pos = ", pos, "v = ", v, " i == 0 && !head", " start = ", start)
if pos != 0 {
return false
}
start = pos + len(v)
//fmt.Println("last start = ", start)
// 匹配最后一个固定部分,先判断末尾是否是模板
} else if i == len(fixed_parts)-1 && !tail {
pos := lastfind(v, title, start)
//fmt.Println("pos = ", pos, "v = ", v, " i == len(fixed_parts)-1 && !tail", " start = ", start)
if pos == -1 || pos+len(v) != len(title) {
return false
}
//fmt.Println("last start = ", start)
} else {
pos := find(v, title, start)
//fmt.Println("pos = ", pos, "v = ", v, " else", " start = ", start)
if pos == -1 {
return false
}
start = pos + len(v)
//fmt.Println("last start = ", start)
}
}
return true
}