變位詞的查詢(上)

2021-09-28 12:43:09 字數 1977 閱讀 1515

這次我們聊乙個比較有意思的話題:變位詞的查詢,這個話題在《程式設計珠璣》**現,此書很經典,偏向於演算法,大家如果能通讀的話,肯定受益匪淺!

什麼是變位詞

不同的單詞,如果其組成的字母相同的話,那麼這些單詞就互為變位詞,譬如pots、stop、 tops這三個單詞就是互為變位詞,都是由字母p、o、t、s組成,但是"pot" 就不與上述單詞互為變位詞,其缺少字母s,「potss」也不是,其多了乙個字母s。

變位詞的查詢就是在給定的一系列候菜單詞中,找出某個單詞的變位詞。大家可以先嘗試著自己想想如何實現,再往下看

怎樣實現變位詞查詢

如果考慮通過列出字串中的各個字母的所有變化換組合來查詢變位詞的話,那麼該演算法是低效的。字串各字母的所有變化組合的數量為其長度的階乘,譬如某個字串有10位,那麼其總的變化數為10!,即3628800種,如果目標詞庫是由1萬個10位長度的字串組成的話,那麼其查詢的所有組合數約為3.6*10的10次方種,顯然其查詢時間將相當漫長。

其正確的處理方法是為目標詞庫的所有字串生成乙個簽名,該簽名就是由字串的各字母排序組成,譬如pots的簽名為opst,同樣stop、tops的簽名也同樣為opst,這樣如果簽名相同的字串就為變位詞了。

基本思路有了以後,我們看看如何具體實現。

實現

程式分為兩部分,第一部分生成指定數量的字串作為目標詞庫,其長度隨機,但不超過10位,為了簡化,字串由隨機小寫字母組成;第二部分輸入乙個字串,在目標詞庫中找出所有與該字串互為變位詞的字串。

生成目標詞庫

詞庫生成通過產生隨機數,來實現隨機長度的隨機小寫字母的組合。為了快捷的生成隨機字母,我們將隨機生成乙個97到122之間的數字,其代表的是小寫字母a到z的ascii編碼,再通過string.fromcharcode()函式來轉換為字母。不熟悉ascii編碼的同學,可以查詢相關資料。**如下:

function create_str()

return str;

}

生成簽名(氣泡排序的實現)

生成簽名的過程就是將字串的各個字母從小到大排序(當然也可以從大到小),如"computer"其字母排序後變成"cemoprtu"。本示例中使用的是氣泡排序演算法,當然也可以用其他排序演算法實現,例如簡單排序、快速排序、希爾排序等。

n個字母進行氣泡排序的方法是:

首先將第乙個字母和第二個字母進行比較,若後乙個比前乙個小,則交換兩個字母,然後比較第二個和第三個,以此類推,直至第n-1個和第n個字母比較完畢。上述過程稱作一趟氣泡排序,其結果是最大的字母被交換到了第n個位置(也就是最後)。

然後進行第二趟氣泡排序,對前n-1個字母進行同樣的操作,其結果就是第二大的字母被交換到了第n-1個位置(也就是倒數第二個)。一直這樣操作,當完成第n-1趟操作後,排序完成,所有字母將由小到大排列。

function get_sign(str)

}

查詢變位詞

簽名生成以後,查詢就變得很簡單,先獲得查詢字串的簽名,再遍歷簽名陣列,如果兩者簽名相同,那麼與簽名陣列當前下標相同的目標詞庫陣列中的元素,就是查詢字串的變位詞。

function search(str)

}return mathstr;  //返回找到的變位詞

}

至此,我們通過簽名的生成與匹配完成了變位詞的查詢,但是目前的方案效能上是有不足的,下一講我們將針對以上的示例做進一步的優化!

更多專業前端知識,請上

【猿2048】www.mk2048.com

變位詞的查詢(下)

實現方案優劣的思考 之前我們的實現方案的優點是一旦目標詞庫的簽名建立後,則變位詞的查詢會變得簡單而快速 缺點是由於在生成目標詞庫時,要為每個詞都生成簽名,導致生成詞庫的時間會變慢,同時會消耗空間。對於那些沒有被查詢到的字串的簽名實際上是浪費的。測試結果 在cpu為inter core i3 2328...

尋找變位詞

程式設計珠璣 五 尋找變位詞 今天的問題是關於變位詞的,首先來看問題的描述 給定一本英語單詞詞典,請找出所有的變位詞集。所謂的變位詞是指,組成各個單詞的字母完全相同,只是字母排列的順序不同。比如,pots stop tops就是變位詞。將變位詞程式組織成三段式的 管道 結構,前乙個程式的輸出檔案將是...

變位詞排序

請編寫乙個方法,對乙個字串陣列進行排序,將所有變位詞合併,保留其字典序最小的乙個串。這裡的變位詞指變換其字母順序所構成的新的詞或短語。例如 和 integral 就是變位詞。給定乙個string的陣列str和陣列大小int n,請返回排序合併後的陣列。保證字串串長小於等於20,陣列大小小於等於300...