马尔可夫链——从一个编程作业中看看程序设计的一些细节问题
2009-10-11 16:15
260 查看
马尔可夫链(Markov Chain),这是我们《程序设计方法学》课程的一个小小的作业,这个作业,主要目的并不是实现算法,而是“如何”实现算法,以及从代码中看出每个人程序设计的“风格”。 因为即使是很少的代码也能暴露出一个编程者的功底和风格。
我觉得这是个很有意思的话题,所以也在这里把我的部分代码发出来,并加以说明以作抛砖引玉。
先稍稍介绍下马尔可夫链,简单地说就是输入一篇文章(其实是单词序列),建立前缀表后缀表,然后根据前缀随机选择后缀,如此迭代,生成一篇“看起来像文章
的随机文本”。当然这只是马尔可夫链的一个应用,不过也算挺典型的。我曾经在开发一些应用的时候用类似的程序来生成测试数据。
我选择C#来实现这一程序。
我的程序流程非常简单:
读取样本 -> 建立前缀、后缀表 -> 生成 -> 输出
根据编程经验和《程序设计实践》,前缀表采用哈希表,后缀表采用链表。
后缀表非常简单,每一个后缀都有一个Next,也就是说后缀本身就是一个链表节点,也就不需要LinkedList<Suffix>来帮忙了。
采用迭代器的方式
foreach (string s in gen.Generate(maxWordCount)) {
Console.Write(s);
Console.Write(" ");
}
这个也算一个迭代器模式的小小的运用吧。其实这个方法和传递委托的方法相差已经很小了,但是我个人喜欢后者。
首先就是我从数据的定义上就出现了问题,因为State里保留的Prefix引用根本没有发挥作用,而Suffix也只是一个头指针,也就是说与其如此复杂还弄出个Prefix.Clone(),还不如直接就把State的小命给革掉。Prefix直接就能映射到Suffix,也省的一个State在中间耽搁着。而Prefix采用了一种“猥琐”的哈希方式,也是有待改进。
附全部程序的源代码下载(敲打我)
我觉得这是个很有意思的话题,所以也在这里把我的部分代码发出来,并加以说明以作抛砖引玉。
目标
先稍稍介绍下马尔可夫链,简单地说就是输入一篇文章(其实是单词序列),建立前缀表后缀表,然后根据前缀随机选择后缀,如此迭代,生成一篇“看起来像文章的随机文本”。当然这只是马尔可夫链的一个应用,不过也算挺典型的。我曾经在开发一些应用的时候用类似的程序来生成测试数据。
程序结构
根据我们老师的要求,程序从文件读入样本数据,从标准输出打印生成的文本,其他没有具体要求。我选择C#来实现这一程序。
我的程序流程非常简单:
读取样本 -> 建立前缀、后缀表 -> 生成 -> 输出
数据结构
根据编程经验和《程序设计实践》,前缀表采用哈希表,后缀表采用链表。后缀表非常简单,每一个后缀都有一个Next,也就是说后缀本身就是一个链表节点,也就不需要LinkedList<Suffix>来帮忙了。
采用迭代器的方式
foreach (string s in gen.Generate(maxWordCount)) {
Console.Write(s);
Console.Write(" ");
}
这个也算一个迭代器模式的小小的运用吧。其实这个方法和传递委托的方法相差已经很小了,但是我个人喜欢后者。
遗憾
这就不得不说文中提到的那个我最大的错误了。首先就是我从数据的定义上就出现了问题,因为State里保留的Prefix引用根本没有发挥作用,而Suffix也只是一个头指针,也就是说与其如此复杂还弄出个Prefix.Clone(),还不如直接就把State的小命给革掉。Prefix直接就能映射到Suffix,也省的一个State在中间耽搁着。而Prefix采用了一种“猥琐”的哈希方式,也是有待改进。
小结
虽然是一个小程序(据说perl只用19行),基本算法也相当简单,但是从中暴露的程序设计的问题却不少,接口职责的设计毫无疑问是程序设计当中的重要部分,“高内聚低耦合”几个字天天挂在嘴皮边上,但真正干活的时候也不是那么容易实现的。身为程序员,难道不应该在这些方面多动动脑筋吗?扩展
在这个程序中,我完全没有考虑API设计中的另一重要环节——异常。并不是疏忽,而是我从一开始就没有把这个列入考虑范围,所以这也是一个可扩展的地方。什么地方抛出异常,抛出什么异常,怎么接到异常,怎么处理,都值得设计。附全部程序的源代码下载(敲打我)
相关文章推荐
- MATLAB中videoinput编程的一些细节问题
- PHP 编程一些及其细微的细节问题
- PHP 编程一些及其细微的细节问题
- java UDP编程中一些小细节问题
- 编程实践中C语言的一些常见细节
- POJ C++程序设计 编程作业—类和对象 编程题#1
- POJ C++程序设计 编程作业—类和对象 编程题 #2
- POJ 算法基础 Assignment: 编程作业—枚举 编程题#1: 画家问题
- OpenGL入门学习之三——绘制几何图形的一些细节问题
- 一些java小细节问题
- 一些细节问题
- 面试问题 面向对象和面向过程编程的一些区别
- 挑战编程 程序设计竞赛训练手册-1.6.1 3n+1问题(3n+1 Problem)
- C# DevExpress WinForm编程 针对一些控件重复度高的属性设置问题的解决方案
- 一些CDockablePane 关闭等编程问题
- 完整安卓项目开发过程和一些细节问题
- 个人总结的一些JavaScript技巧、实用函数、简洁方法、编程细节
- 【编程之美】一些细节的总结
- Java 编程技术中汉字问题的一些url收藏
- 最近要做个项目,遇到一些关于ansys问题,看看兄弟们能否帮我解决?