[记录]乱数假文生成器的制作过程.

我的乱数假文生成器已经正式发布了访问地址为:http://bugunow.com/lipsum

起因…

前两天在为系的网站设计样式稿,当我觉得页面太空了想要塞点文字的时候,花了不少时间找素材.这时候我想到当初我在一位台胞的博客上看到一篇有关假文的生成工具(具体我已经不记得网址了),于是我翻山越岭的找啊,找到了没有中文的LoremIpsum和只有繁体中文的乱数假文生成器.或许我不知道它在大陆还有什么别的叫法,于是激情一燃就不可收拾,完全忘了Google Translate就是最好的假文生成利器…

什么是乱数假文生成器?

如果非要给它下一个定义的话,乱数假文生成器就是一个:能生成一定长度的没有意义,但乍一眼望去又像极了自然文字的工具.

具体内容点这里查看.

开始动手.

在没有分析任何中英文差别下,我开始了编码工作,也因为时间的关系我并没有在如何实现这些功能的性能上考虑太多.

因为上面的原因给我这个网站埋下了2个伏笔,特别是性能上.这些稍候再说.

考虑1:在生成之前,这些”汉字”从哪里来?

个人觉得这些汉字应该要存在某个”汉字库”里面,从汉字库里随机抽取汉字堆叠生成一段假文.于是我决定做一个”字库”,存放一个数量级的没有重复的汉字.那么在做生成器之前还要做一个字库存储器.突然觉得别看是一个小东西,但是真正实现起来还着实麻烦呢!

注意:我在这里其实犯了一个错,并且现在才恍然大悟.那么我将会在揭示伏笔的时候一起道出这个让我南辕北辙并且现在还没有实现的功能吧.

编写字库这个程序的时候是我最花时间的时候,因为自己都在做web开发,很少做winform开发,所以一开始搞winform的时候就拉了好多有的没的的控件,为了它的美观花了不少功夫.其次,在编写代码的时候我非常注意OO,并且尽量让每个Method中的代码不超过10行,做了好多防止误操作的检测,还大玩特玩起了事件机制.所以结果由此而知,我竟然做出了一个”产品”出来,而不是只做一个自己临时用一用的小工具而已.

动手1:实现字库的思路如下:

1.首先写了一个匹配英文字母和空格的正则表达式,写了一个平常经常使用的标点符号数组.

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

 

 

posted @ 2010-05-16 02:20  Snake@Net  阅读(1566)  评论(2编辑  收藏  举报