文章目錄
我的亂數假文產生器已經正式發布了訪問地址為:http://bugunow.com/lipsum
起因…
前兩天在為系的網站設計樣式稿,當我覺得頁面太空了想要塞點文字的時候,花了不少時間找素材.這時候我想到當初我在一位台胞的部落格上看到一篇有關假文的產生工具(具體我已經不記得網址了),於是我翻山越嶺的找啊,找到了沒有中文的LoremIpsum和只有繁體中文的亂數假文產生器.或許我不知道它在大陸還有什麼別的叫法,於是激情一燃就不可收拾,完全忘了Google Translate就是最好的假文產生利器…
什麼是亂數假文產生器?
如果非要給它下一個定義的話,亂數假文產生器就是一個:能產生一定長度的沒有意義,但乍一眼望去又像極了自然文字的工具.
具體內容點這裡查看.
開始動手.
在沒有分析任何中英文差別下,我開始了編碼工作,也因為時間的關係我並沒有在如何?這些功能的效能上考慮太多.
因為上面的原因給我這個網站埋下了2個伏筆,特別是效能上.這些稍候再說.
考慮1:在產生之前,這些”漢字”從哪裡來?
個人覺得這些漢字應該要存在某個”漢字型檔”裡面,從漢字型檔裡隨機抽取漢字堆疊產生一段假文.於是我決定做一個”字型檔”,存放一個數量級的沒有重複的漢字.那麼在做產生器之前還要做一個字型檔儲存空間.突然覺得別看是一個小東西,但是真正實現起來還著實麻煩呢!
注意:我在這裡其實犯了一個錯,並且現在才恍然大悟.那麼我將會在揭示伏筆的時候一起道出這個讓我南轅北轍並且現在還沒有實現的功能吧.
編寫字型檔這個程式的時候是我最花時間的時候,因為自己都在做web開發,很少做winform開發,所以一開始搞winform的時候就拉了好多有的沒的的控制項,為了它的美觀花了不少功夫.其次,在編寫代碼的時候我非常注意OO,並且盡量讓每個Method中的代碼不超過10行,做了好多防止誤操作的檢測,還大玩特玩起了事件機制.所以結果由此而知,我竟然做出了一個”產品”出來,而不是只做一個自己臨時用一用的小工具而已.
動手1:實現字型檔的思路如下:
1.首先寫了一個匹配英文字母和空格的Regex,寫了一個平常經常使用的標點符號數組.
2.因為我只想讓字型檔擁有”漢字”這唯一的屬性,所以就定義了一個List<char>作為字型檔來所有的”漢字”
3.從外部txt檔案中讀取文檔作為Source.
4.去除Source中所有的”非法”字元,空白,和英文單詞.
5.迴圈Source中的每一個”漢字”並且查看字型檔中是否已經含有這個漢字,如果字型檔中沒有這個漢字的話,則添入,否則繼續迴圈.
6.迴圈結束並且序列化成二進位文檔儲存以備後需.
就這6跳步驟,我1個小時完全就能做出來了,出了思考的時間之外,就是上面說過的,太追求”完美”了..
動手2:匯入字型檔.
上網下載了一個長達6MB多的txt小說扔進”工廠”裡加工之後字型檔的漢字數量由0變成了3500多不由得意了一下.不過,耗時1分多鐘….
此時進入產生器編碼階段,我流利地建立了一個工程(類庫),決定要把它做到足夠通用.
思考2:產生器的流程:
1.構造一個Lorem Ipsum類,給出漢字字型檔和英文詞庫的path,再給出分行符號符號(因為在web換行是<br/>而在win下,分行符號是n).
2.執行製造假文Method,並傳進一個LoremIpsumModel參數(實體類)裡麵包含了各種產生選項.
3.根據參數計算出假文應該有多少段落,並且每段多少個字.
4.開始隨機取漢字堆假文.並且在段落的最後加入”結束標點符號”和分行符號.
5.根據參數插入零星英文單詞和標點符號.
6.返回假文.
由上面的流程可以看出將要做出以下幾個東西:
1.中英文標點常量,並且還要區分結束和非結束標點.
2.英文字型檔(真悲劇現在才想到).
3.假文分段的演算法,計算英文單詞個數的演算法,標點符號個數的演算法(包括在方圓幾個漢字之內不能重複出現標點).
悲劇,因為考慮到英文單詞更能表現一個字型的全能性(中英文都好看),於是停下了手中寫產生器的工作,開始寫英文詞庫.
英文詞庫處理工具比漢字字型檔要來的方便的多,一個正則就能揪出所有的英文單詞,為了效率,這個工具寫的很脆弱,花了半小時,之後立馬刪除了.
最後製作產生器除了考慮通用性之外,很迅速的就寫出了具體的產生方法,在winform和web上都能通用讓我快樂,終於也跨”平台”了一次!呵呵..
動手3:測試假文產生器.
幾次debug搞定死迴圈錯誤之後,第一次測試非常的不理想.雖然的確如我所願產生了一篇假文,500個字,3個自然段,標點正常.結果一大堆亂七八糟的字,通篇下來看不到一個”你“或者”我”字.並且那些字的筆畫也太多了吧,即便是天書也不能這麼天書,太不真實了.
此時才開始思考中英文差別的問題,英文是拼音文字,n個字母才組成一個單詞,並且由空格分開,雖然占的空間多,但是比較優美,通篇胡亂的英文乍一看上去還是非常真實的(也可能因為本人英文閱讀水平太差,門外漢看不出行內的好壞),因為都是以單詞的形式呈現出來的.
簡體中文在使用時筆畫繁多的漢字不多,並且有時候一個漢字包含了許多意思,並且不常用到.那本小說大概神神鬼鬼的內容寫了太多,字雖然有3500多個,但是總體來說效果不好.我想,我們最最常用的漢字有多少個呢?1000多左右吧,多餘的2500多個應該算是使用頻率不是那麼頻繁或者根本就不頻繁的漢字.於是我決定刪掉漢字字型檔,再導一個.
這次目標盯上了魯迅和朱自清兩位老先生的作品,但是實踐結果是:不夠白話文一些,還是不理想!最後決定在部落格上下手,自己的博文,老徐的,老趙的,老七老八的文章複製了大概26k左右,匯入了1200多個字.這才有了不錯的效果!
伏筆之一:沒有分析中英文差距和中文特色導致花費很多時間在調整字型檔上,到此終於解決.
伏筆二:效能.做了一次非常非常簡陋的測試,迴圈10000次產生1000字的假文花了7秒多..還是比較久的,並且CPU佔用率超過70%.還好這個工具不是特別多人用,而且我的工具目前訪問人數不是特別多,也就先不擔心了.
最後花了點時間微調標點符號和段落的演算法,開始搞網站了.網站因為功能單一沒啥好說的,只是花了不少時間在設計上面.現在也在上傳到主機的途中.
說說缺點:
1.沒有根據漢字的使用率頻繁與否產生一段更真實的假文.
之前還在想要不要做一個Key Value Pair,key裡放的字漢字,Value放的是頻率,對比重複一次自加1,然後根據一定演算法擷取常用字.這是時間換空間的做法.但個人認為根本沒這必要(寫這篇文章的時候才想到的).首先字型檔再怎麼大也超不過10M,10M的txt文本至少也有上千萬個字吧,這種業務,字型檔放個50000字就算小題大做了,那麼產生的字型檔檔案也不過50多k吧.另外,擷取數組的index位的時間複雜度是O(1),不會因為字型檔的文字多而導致效能問題.一個字型檔重複的字多了,被選中的幾率就搞了,代碼寫起來也簡單了,記憶體和硬碟空間的佔用也完全不是問題.那麼我何必還大費周章去搞漢字字型檔處理工具呢?Orz….
update at 2010/5/16 10:00:使用以上的思路重新匯入了一趟字型檔,感覺效果還是不錯滴.
2.沒有可讀性.
我也很想讓這些文字看來有一定的可閱讀性,也就是具有至少”主,謂,賓”三個關鍵組成部分.但是這樣就要給所有字型檔裡面的文字添加這些屬性.另外小弟不才暫時沒有想到很好的批處理辦法.所以這個功能等有思路能實現一個比較省時的方法的時候再來做吧.
3.功能不多.
是,國外的還能產生N個段落,N個字,列表的N個項目等等..這些功能非常簡單,未來將會再添加上.
在最後發布到伺服器的時候出現了System.Security.SecurityPermisson的問題,從堆棧錯誤上來看,是還原序列化時產生的問題,折騰了半天不知其所以然來,所以決定明天再修改一下程式,降低存取權限,畢竟godaddy上客戶是待宰的羔羊..
埋下又一顆種子,我的獨立部落格:http://bugunow.com/blog