使用程式碼列出金庸小說中使用過的所有成語

i042416發表於2019-10-31

去年的今天,金庸與世長辭,當時Jerry在成都地鐵一號線下班的路上得知了這個訊息,回到家立即寫了一篇文章來悼念: 金庸的武俠世界和SAP的江湖

一年的時間轉瞬即逝,大家都忙碌於各自的生活,很多人對金老的離世已經淡忘了,不過Jerry這種金庸的死忠粉,對於這個一週年忌日還是記得很清楚的。

因為Jerry手上事情很多,沒時間在這個特殊的日子寫文章紀念了,就發一小段程式碼吧。

需求:列出金庸任意一本小說裡出現的所有成語。

實現:Jerry部署在Github上的一個web應用,連結如下:

首先點選超連結“成語全集”:

使用程式碼列出金庸小說中使用過的所有成語

點選之後,儲存於該web應用本地儲存的一個文字檔案裡的全部19830個成語,以樹的形式載入到記憶體中,並顯示在網頁上:

使用程式碼列出金庸小說中使用過的所有成語

然後複製一本金庸小說的內容,貼上到網頁的“內容”區域,點選按鈕“測試”:

使用程式碼列出金庸小說中使用過的所有成語

可以看到僅僅用了246毫秒,就將這部一百多萬字的《倚天屠龍記》裡出現的所有成語,以紅色高亮的方式高亮出來。

使用程式碼列出金庸小說中使用過的所有成語

這個功能咋實現的?Chrome開啟Jerry的網頁,F12開啟開發者工具,就能看到JavaScript原始碼,當然也可以從我的 Github上獲得.

Jerry簡單講下實現原理。Web應用裡有一個文字檔案,裡面維護了漢語裡全部的成語,透過分號分隔。

使用程式碼列出金庸小說中使用過的所有成語

執行時,這些內容會被載入到記憶體中,構建成一棵樹,如下圖所示:

使用程式碼列出金庸小說中使用過的所有成語

其中葉節點以屬性end為true區分。

成語檢索的核心邏輯位於search函式里,讓我們用《笑傲江湖》裡一句響亮的口號“日月神教千秋萬載,一統江湖”來單步除錯,瞭解其實現邏輯。

使用程式碼列出金庸小說中使用過的所有成語

進入165行的外層while迴圈,再進入173行的內層for迴圈,檢測是否有測試字串第一個字元“日”開頭的成語。因為成語是由4個字元組成,所以需要用內層for迴圈逐一試探,如果遇到tblCur.end為true的元素,說明在測試字串中發現了一個成語。

下圖是內層for迴圈第一次執行後的tblCur內容:

使用程式碼列出金庸小說中使用過的所有成語

內層迴圈執行第二次,此時tblCur指向一棵由所有“日月”開頭的成語組成的樹:

使用程式碼列出金庸小說中使用過的所有成語

執行內層迴圈的第三次迭代,因為在樹“日-月”這個分支下面沒有“神”這個節點,所以結束當前的內層迴圈,透過break返回到外層的while迴圈,進行輸入字串第二個字元“月”的新一輪試探,以此類推。

使用程式碼列出金庸小說中使用過的所有成語

最後從“千”這個字元出發,沿著記憶體中的樹經過路徑"秋-萬",最後來到end屬性為true的葉節點“載”,記下“千”在輸入字串中的偏移量,存到一個陣列arrMatch中去。

使用程式碼列出金庸小說中使用過的所有成語
使用程式碼列出金庸小說中使用過的所有成語

待輸入字串全部試探完畢後,根據arrMatch中存放的偏移量,高亮顯示對應的字串,完成檢索。

使用程式碼列出金庸小說中使用過的所有成語

樹這個資料結構在這個需求的實現裡有著完美的表現。

金庸雖然離開了我們,但他筆下那些人物和發生的故事,將永遠流傳於這個世上。

更多閱讀

使用程式碼列出金庸小說中使用過的所有成語
logo.jpg

要獲取更多Jerry的原創文章,請關注公眾號"汪子熙":


使用程式碼列出金庸小說中使用過的所有成語


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/24475491/viewspace-2662127/,如需轉載,請註明出處,否則將追究法律責任。

相關文章