创意标题匹配(golang)

160 阅读2分钟

问题描述

在广告平台中,为了给广告主一定的自由性和效率,允许广告主在创造标题的时候以通配符的方式进行创意提交。线上服务的时候,会根据用户的搜索词触发的 bidword 对创意中的通配符(通配符是用成对 {} 括起来的字符串,可以包含 0 个或者多个字符)进行替换 ,用来提升广告投放体验。例如:“{末日血战} 上线送 SSR 英雄,三天集齐无敌阵容!”,会被替换成“帝国时代游戏下载上线送 SSR 英雄,三天集齐无敌阵容!”。给定一个含有通配符的创意和一句标题,判断这句标题是否从该创意替换生成的。

思路

  1. 解析模板:找出固定的部分
  2. 检查占位符:判断占位符是否出现在开头或结尾
  3. 匹配标题:根据固定部分和占位符的情况,匹配标题字符串。

代码

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
}

参考链接:【2024字节青训·易】创意标题匹配_创意字符匹配-CSDN博客