周末遐想(計算最長英語單詞鏈)


0.前言

剛從北京回來,恰逢周末,好友近日也不在武漢。又因在博客中的一些交流,恰好看見微軟鄒欣老師關於《現代軟件工程作業 -- 計算最長英語單詞鏈》的博文。因此得空,按照需求分析到設計到實現以及測試和效能分析的流程,編寫程序,分析程序並攥寫一篇博文。考慮到時間比較有限,隨筆之中難免出現語句不通,錯別字,以及一些錯誤分析等等現象,還望見諒。

  周末時間只有一天,此篇博文包括代碼均有很多坑!嘿嘿~

  《計算最長英語單詞鏈》 https://www.cnblogs.com/xinz/p/7119695.html

  Github地址: https://github.com/yuan574954352/WordChain

1.需求分析(略)

英語的接龍吧:一個文本文件中有N 個不同的英語單詞, 我們能否寫一個程序,快速找出最長的能首尾相連的英語單詞鏈,每個單詞最多只能用一次。最長的定義是:最多單詞數量,和單詞中字母的數量無關。

例如, 文件里有:

Apple

Zoo

Elephant

Under

Fox

Dog

Moon

Leaf

Tree

Pseudopseudohypoparathyroidism

最長的相連英語單詞串為:  apple - elephant – tree,  輸出到文件里面,是這樣的:

              Apple

              Elephant

              Tree

  1. 設計以及主要實現過程

PSP】

PSP2.1

Personal Software Process Stages

預估耗時(分鍾)

實際耗時(分鍾)

Planning

計划

10

8

· Estimate

· 估計這個任務需要多少時間

960

-

Development

開發

720

700

· Analysis

· 需求分析 (包括學習新技術)

15

10

· Design Spec

· 生成設計文檔

10

15

· Design Review

· 設計復審 (和同事審核設計文檔)

10

12

· Coding Standard

· 代碼規范 (為目前的開發制定合適的規范)

10

15

· Design

· 具體設計

20

22

· Coding

· 具體編碼

480

500

· Code Review

· 代碼復審

15

20

· Test

· 測試(自我測試,修改代碼,提交修改)

60

30

Reporting

報告

30

35

· Test Report

· 測試報告

20

22

· Size Measurement

· 計算工作量

5

7

· Postmortem & Process Improvement Plan

· 事后總結, 並提出過程改進計划

20

20

合計

 

695

708

 

二、解題思路

這個題的解題思路其實很簡單啦,也就是說Make it work的實現方式很容易想到,但如何使程序高效率的實現就需要深入考慮了。首先,思考一個基本的方向,核心算法就是使用圖論的相關知識,OK。這里關於圖論就不詳細敘述,簡單地以個人的語言來敘述一下:

【圖論】

圖論的起源就可以追溯到歐拉(Leonhard Euler)所處的那個年代。1736年,歐拉來到了普魯士的Konigsberg(哈哈,康德老家),發現當地人就有一項消遣活動,就是試圖將下圖中的每座橋恰好走過一遍並回到原出發點。但從來沒有成功過。

         

 

歐拉呢,就想着證明為什么一直沒成功啦~~~~

歐拉就把這個問題抽象成 點與線的構造,這不就是圖嘛!

至於為什么不可能。可以百度搜索【歐拉七橋問題的證明】

  1. 圖的分類

1)無向圖:就是說兩個頂點沒有明確的指向關系,只有一條邊相連。就我目前的知識而言,我所了解的關於圖論的大部分算法都是基於無向連通圖的。

2)有向圖:說白了,就是有方向的圖唄!!嘿嘿,但是有方向,一定要記清幾個定義!這也是順理成章的定義,就是In與out!在無向圖中,一個頂點有多少條可以出去的路,就這個頂點的度。顯然,在有向圖就會分為 出度與入度。

事實上,度與邊是有數學關系的,出度與入度也是一樣。度與邊的關系也是【歐拉七橋問題】關鍵點啦。

(3)連通圖:任意兩個頂點之間是連通的

(4)非連通圖:無向圖中,存在兩個頂點之間是不連通的

(5)強連通圖:針對有向圖而言的A->B 而B 不能 ->A

(6)非強連通圖:有向圖中存在兩個頂點之間是不連通

到后面反過來思考,其實我們求解的最長單詞鏈就是非強連通圖哦,那么如果有算法將非強連通圖轉成類似於無向圖的連通圖的,會不會提高效率呢~,哈哈。遐想遐想!

 

好啦。一口氣簡單介紹了圖的來歷與分類。那么現實抽象成圖,圖抽象成數字!就可以成為兩個向量:

Vertice={結點1,結點2,.....}

Edge={(1,2),(2,3),(4,6)........}

這兩個向量就能描述一張圖嘛。而且也好對圖進行運算。

OK!我們說提高程序效率從兩方面入手,一個是程序輸入參數的數據組織結構,也就是數據結構啦,另一個就是算法。

第一:數據結構

關於圖的數據結構,常規的有:鄰接矩陣,壓縮表呀,十字鏈表呀等等,我也記不清啦。這里就牽扯到 這種數據結構一方面提高程序效率另一方面要盡可能的減小存儲空間,這也就是大多數《數據結構》的書,都分析時間需求,存儲空間。

第二:算法

就我了解的呀,大的思想類似於貪婪算法分而治之動態規划。好像克瑞斯托,以及Prim算法都是基於貪婪算法的啦,但是好像這些都是基於無向連通圖的,我也一直沒把我實際需要解決的問題(計算最長單詞鏈)直接套用某個算法的,所以掌握這些算法的思想最重要啦,嘿嘿!  就像室內定位的研究領域,想找某個算法直接套用根本不可能啦,但是運用類似於隱馬爾科夫,條件隨機場呀的思想還是可以的~~~扯遠了。。。哈哈

【核心思想】

假設結點是:AppleElephanttree.等等,結點與結點的邊就是根據首尾字母是否相同來構造的。這邊就能得到V,E。構成一個圖。請注意:我們一定要構造的是一個非強連通的有向圖!

利用圖去生成樹,利用樹去生成路徑!

這個思想還是很重要的,據說有一個中國人就發現了一種樹,改進了一個算法。我印象在本科階段上《數據挖掘與分析》的時候,提及過。韓嘉煒老師的FP-Tree.

所以,我也在遐想,能不能也搞一個專用於處理非強連通的有向圖生成的樹,這個樹便於獲取最長/最短路徑~~~當然是遐想啦,還是務實!其實有時候國內就是這樣,很多想法不敢去實施,因為一旦實施失敗便意味着你的論文將空盪盪,這個以論文數量論成績的環境里,還是要隨下大流~~【笑哭】

說到FP-Tree又在聯想我這個實際問題,所謂的FP就是頻繁模式(frequent pattern),那么我能否也構造一個FP-Tree去找出input.txt中哪些單詞總是相伴出現的呢?這又牽扯到關聯規則啦,我可沒有那么多時間在去扯別的領域的知識啦,“啤酒與尿布”故事總會讓我以為關聯規則很簡單,事實上可不是這樣,有時需要用更嚴格的統計學知識來控制規則的增殖!

 

OK!運用“敏捷”思想,第一個想到的當然是深度優先生成樹。生成n(結點數)個樹,獲取每個樹的最長鏈!最后排序這些最長鏈,也就得到我們想要最最長鏈!

這是“敏捷”思想在促使我這樣做,因為我知道這樣做,I can make it work!至於后面如何改進就是后話了!

【核心思想圖】

 

 

三、其他遐想

其實關於圖論在工程上實現要考慮的細節很多,那么考慮到我實際的問題,我想。

第一,是用BFS還是DFS?

BFS就是廣度優先生成樹,當然有些書籍把它稱之為寬度優先生成樹。DFS是深度優先生成樹。說實在的,在以前本科階段的學習,我只知道有這兩種方案可以生成樹。生成的樹可能只是遍歷的順序不同吧,對此也沒有什么好的印象。那個時候,就想着混學分。恨不得早點考完,哈哈。

從理論上講,這兩個算法都能夠在大致相同的時間里生成整個單詞森林!【這個時間是節點數量V和邊的數量E之和的線性函數,即O(V+E)】。那BFS和DFS的在工程上的區別又是如何呢!就拿目前這個問題來說吧,深度優先,他可以比廣度優先,提前生成某棵樹的一個鏈路。 這樣是不是可以運用多線程的思想,來提前后面的后續操作呢? 當然,這只是遐想,而且這種操作應該需要單詞量很多的情況。

 

四、效率圖,考慮到已經到晚上10點啦,下班啦,要去跑步啦啦.....就做了幾個就不粘貼上來了。哈哈~~~ 下次有周末再補上來。。嘻嘻。有興趣的讀者也可以自行測試。代碼已上傳Github。

五、網頁版的程序,使用Spring MVC框架,control層調用程序里的lib()即可

                                                        寫於   地大(武漢)工程研究中心    2018/7/15 (周日)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM