github.com/qiuhoude/go-web@v0.0.0-20220223060959-ab545e78f20d/algorithm/leetcode/add-and-search-word-data-structure-design_test.go (about)

     1  package leetcode
     2  
     3  import (
     4  	"testing"
     5  )
     6  
     7  // 211. 添加与搜索单词 - 数据结构设计
     8  // https://leetcode-cn.com/problems/add-and-search-word-data-structure-design/
     9  
    10  type WordDictionary struct {
    11  	Next  map[rune]*WordDictionary
    12  	isEnd bool
    13  }
    14  
    15  /** Initialize your data structure here. */
    16  func Constructor() WordDictionary {
    17  	next := make(map[rune]*WordDictionary)
    18  	return WordDictionary{Next: next, isEnd: false}
    19  }
    20  
    21  /** Adds a word into the data structure. */
    22  func (this *WordDictionary) AddWord(word string) {
    23  	rArr := []rune(word)
    24  	cur := this
    25  	for _, c := range rArr {
    26  		next, ok := cur.Next[c]
    27  		if !ok {
    28  			n := Constructor()
    29  			next = &n
    30  			cur.Next[c] = next
    31  		}
    32  		cur = next
    33  	}
    34  	cur.isEnd = true
    35  }
    36  
    37  /** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */
    38  func (this *WordDictionary) Search(word string) bool {
    39  	if len(word) == 0 {
    40  		return false
    41  	}
    42  	return march(this, []rune(word), 0)
    43  }
    44  
    45  func march(n *WordDictionary, word []rune, index int) bool {
    46  	if len(word) == index {
    47  		return n.isEnd
    48  	}
    49  	c := word[index]
    50  	if c != '.' {
    51  		next, ok := n.Next[c]
    52  		if !ok {
    53  			return false
    54  		} else {
    55  			return march(next, []rune(word), index+1)
    56  		}
    57  	} else {
    58  		for _, next := range n.Next { //匹配所有边
    59  			if march(next, []rune(word), index+1) { // 只要有一个匹配就返回
    60  				return true
    61  			}
    62  		}
    63  		return false
    64  	}
    65  }
    66  
    67  /**
    68   * Your WordDictionary object will be instantiated and called as such:
    69   * obj := Constructor();
    70   * obj.AddWord(word);
    71   * param_2 := obj.Search(word);
    72   */
    73  
    74  func TestSearch(t *testing.T) {
    75  	type args struct {
    76  		word    []string
    77  		searchW []string
    78  	}
    79  	tests := []struct {
    80  		name string
    81  		args args
    82  		want []bool
    83  	}{
    84  		{"xx", args{[]string{"bad", "dad", "mad"},
    85  			[]string{"", "pad", "bad", ".ad", "b.."}},
    86  			[]bool{false, false, true, true, true}},
    87  	}
    88  
    89  	for _, tt := range tests {
    90  		t.Run(tt.name, func(t *testing.T) {
    91  			obj := Constructor()
    92  			for _, w := range tt.args.word {
    93  				obj.AddWord(w)
    94  			}
    95  			for i, v := range tt.args.searchW {
    96  				got := obj.Search(v)
    97  				if tt.want[i] != got {
    98  					t.Errorf("%s search %d %s got %v want %v", tt.name, i, v, got, tt.want[i])
    99  				}
   100  			}
   101  		})
   102  	}
   103  
   104  }