110 lines
2.1 KiB
Go
110 lines
2.1 KiB
Go
package main
|
|
|
|
type StringMap struct {
|
|
Map SubStringMap
|
|
}
|
|
|
|
func NewStringMap() *StringMap {
|
|
return &StringMap{
|
|
Map: map[byte]*StringMap{},
|
|
}
|
|
}
|
|
|
|
func (sm *StringMap) CombineAllSubStrings(prefix string, rev bool) []string {
|
|
if len(sm.Map) == 0 {
|
|
return []string{prefix}
|
|
}
|
|
out := []string{}
|
|
for chr, Map := range sm.Map {
|
|
if rev {
|
|
out = append(out, Map.CombineAllSubStrings(string(chr)+prefix, rev)...)
|
|
} else {
|
|
out = append(out, Map.CombineAllSubStrings(prefix+string(chr), rev)...)
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
|
|
func (sm *StringMap) Add(word string, rev bool) {
|
|
if len(word) == 0 {
|
|
return
|
|
}
|
|
take := 0
|
|
if rev {
|
|
take = len(word) - 1
|
|
}
|
|
sub, ok := sm.Map[word[take]]
|
|
if !ok {
|
|
sub = NewStringMap()
|
|
sm.Map[word[take]] = sub
|
|
}
|
|
if rev {
|
|
sub.Add(word[:take], rev)
|
|
} else {
|
|
sub.Add(word[1:], rev)
|
|
}
|
|
}
|
|
|
|
type SubStringMap = map[byte]*StringMap
|
|
|
|
type WordFilter struct {
|
|
Prefixes *StringMap
|
|
Suffixes *StringMap
|
|
Words map[string]int
|
|
}
|
|
|
|
func Constructor(words []string) WordFilter {
|
|
Prefixes := NewStringMap()
|
|
Suffixes := NewStringMap()
|
|
Words := map[string]int{}
|
|
|
|
for idx, word := range words {
|
|
Words[word] = idx
|
|
Prefixes.Add(word, false)
|
|
Suffixes.Add(word, true)
|
|
}
|
|
return WordFilter{
|
|
Prefixes: Prefixes,
|
|
Suffixes: Suffixes,
|
|
Words: Words,
|
|
}
|
|
}
|
|
|
|
func (wf *WordFilter) F(prefix, suffix string) int {
|
|
prefix_base, ok := wf.Prefixes, true
|
|
for i := range prefix {
|
|
prefix_base, ok = prefix_base.Map[prefix[i]]
|
|
if !ok {
|
|
return -1
|
|
}
|
|
}
|
|
suffix_base := wf.Suffixes
|
|
for i := len(suffix) - 1; i >= 0; i-- {
|
|
suffix_base, ok = suffix_base.Map[suffix[i]]
|
|
if !ok {
|
|
return -1
|
|
}
|
|
}
|
|
prefix_found := map[string]bool{}
|
|
for _, found := range prefix_base.CombineAllSubStrings(prefix, false) {
|
|
prefix_found[found] = true
|
|
}
|
|
|
|
max := -1
|
|
for _, found := range suffix_base.CombineAllSubStrings(suffix, true) {
|
|
if _, ok := prefix_found[found]; ok {
|
|
idx := wf.Words[found]
|
|
if idx > max {
|
|
max = idx
|
|
}
|
|
}
|
|
}
|
|
return max
|
|
}
|
|
|
|
/**
|
|
* Your WordFilter object will be instantiated and called as such:
|
|
* obj := Constructor(words);
|
|
* param_1 := obj.F(prefix,suffix);
|
|
*/
|