字符串正則匹配問題算法題

題目

設計一個支持以下兩種操作的數據結構:

void addWord(word)
bool search(word)

search(word) 可以搜索文字或正則表達式字符串,字符串只包含字母 .a-z 。
. 可以表示任何一個字母。

示例:

addWord("bad")
addWord("dad")
addWord("mad")
search("pad") // false
search("bad")  // true
search(".ad")  // true
search("b..")  // true

思路分析

  • 這道題要求字符串既可以被添加、又可以被搜索,這就意味著字符串在添加時一定要被存在某處。鍵值對存儲,我們用 Map(或對象字面量來模擬 Map)。
  • 這里為了降低查找時的復雜度,我們可以考慮以字符串的長度為 key,相同長度的字符串存在一個數組中,這樣可以提高我們后續定位的效率。
  • 在搜索前需要額外判斷一下,傳入的到底是普通字符串,還是正則表達式。若是普通字符串,則直接去 Map 中查找是否有這個 key;若是正則表達式,則創建一個正則表達式對象,判斷 Map 中相同長度的字符串里,是否存在一個能夠與這個正則相匹配。

代碼

class WordDictionary {
  constructor() {
    this.words = {}
  }

  addWord(word) {
    if (this.words[word.length]) {
      this.words[word.length].push(word)
    } else {
      this.words[word.length] = [word]
    }
  }

  search(word) {
    // 若該字符串長度在 Map 中對應的數組根本不存在,則可判斷該字符串不存在
    if (!this.words[word.length]) {
      return false
    }

    // 緩存目標字符串的長度
    const len = word.length
    // 如果字符串中不包含‘.’,那么一定是普通字符串
    if (!word.includes('.')) {
      return this.words[len].includes(word)
    }
    // 否則是正則表達式,要先創建正則表達式對象
    const reg = new RegExp(word)
    return this.words[len].some((item) => {
      return reg.test(item)
    })
  }
}

const wordDictionary = new WordDictionary()
wordDictionary.addWord("bad")
wordDictionary.addWord("dad")
wordDictionary.addWord("mad")
wordDictionary.search("pad") // false
wordDictionary.search("bad")  // true
wordDictionary.search(".ad")  // true
wordDictionary.search("b..")  // true
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。