问题复杂度

我常常低估解决一个问题需要的时间,大致看一眼问题,规划一下思路,然后考虑考虑是否可行,凭感觉给出一个时间。

可能对于熟悉的或者解决过的问题,这样子估计的误差不是太大。一旦遇到未知的领域,结果却是谬之千里。

当解决未知问题的时候,在纸上勾画出大致的算法是一种情形,一行行代码敲进去的时候,往往会变成另外的情形。大量的细节性的问题没有考虑周全。有时认为困难的地方,反倒是最简单的。那些认为无足轻重的枝枝叶叶,形成一股极大的阻力,缠绕在四肢,降低前进的步伐。

周四吧,吃过晚饭之后,突然想写一个程序匹配正则表达式。没有任何外加原因,我自己都奇怪,仿佛上帝说,你写个那样的程序吧。

于是我就动手开始了,心想看起来不太难,一个晚上搞定吧。

先是写了二百行左右的代码,最后发现整个思路都有问题,第二天又重新开始写,写了又改,改了又写。最后大致剩三四百行。

一开始我试图直接从正则表达式构造一个dfa,也就是第一天晚上的想法,后来发现太困难放弃了。又看了看书,也就是那本dragon book。周五一天,完成了从正则表达式到nfa的程序。表面上看使用Thompson构造法似乎很容易就能得到结果了,但我低估了实现数据结构表示形式以及操作等细节实现的复杂度。再加上一大部分调试的时间,磨蹭了一天才完成。

昨天跟一个同学出去打台球了,晚上回来看了部电影,没写程序。

今天又折腾了一天,主要是将nfa转换成dfa,也就是那个很简单的子集构造算法,描述起来是很简单的,感觉也不复杂。可我慢慢腾腾的花了一天才搞定。九点钟的时候,得到了一个还算满意的结果。

完成的时候,心情挺不错。似乎费心力的那么长的时间不算什么。也许大部分人都是这样子,在完成一件事情之后,忽略掉为完成它而付出的努力。

很多时候,不单是程序,通常生活中也常常低估事情的复杂性,人的力量,凭感觉似乎能做很多事情,其实一段时间之内,真正能做好的,也就那么一两件而已。

使用odbc操作Excel

事出有因,昨天我的old daddy要我帮他把一些Excel里的数据写进foxpro的数据库里,按照要求的表结构,还要做一些加工处理。(我晕,这年头居然还有人在用foxpro)

于是乎,我又装上那个n年都没有用过的visual studio 6.0了,看了半天的msdn,简单的小玩了一下foxpro,感觉太过于弱智,不太习惯。

心想既然foxpro也算一个小的数据库,应该支持odbc连接吧,然后我就能用java或python之类的语言直接操作了。

没想到打开odbc数据源的设置一看,居然连Excel都支持odbc,真没想到

从Excel里导出数据,通常的想法是,可以存成csv或者xml,然后随便拿一个语言就分析了,没想到微软更是体贴,直接建一个dsn,然后写sql语句吧,呵呵

顺便说一下,excel里的表的名称是[sheet1$]之类的,必须写成select * from [sheet1$]来选择sheet1,具体为什么去问M$吧。

脚本语言

今天大致读了一下某开源软件的源代码,不过里面的文档都是分几个版本的,有*.html.en的,有*.html.fr的,比较让人不爽的是,需要把相应的文件改成.html才能当成html打开,当然,程序员都喜欢偷懒,我这个自诩的程序员也不例外,顺手用python写了个小程序把这些搞定,呵呵,越来越觉得python好用了。

我一直都是C/C++的狂热分子,不过最近越来越觉得脚本的妙处了,动态语言有着编译语言不可比拟的方便快捷,简单易用,不像C之类的时刻都要操心每一个变量和细节,可以顺手拈来写个小程序完成手头急需的工作,大大简化编程所需的时间和精力。

大程序里如果嵌入一些脚本作接口同样可以简化软件的复杂程度,就像现在的浏览器javascript,,flash里的actionscript,特别是网络游戏。这正凸现了人们解决复杂问题的处理思想,一层层的简化封装,这样就能在大脑可处理的情况下完成极端复杂的事务。

以前我觉得在程序中嵌入脚本比较难,尝试过lua和python之后觉得还是挺简单的,呵呵,其实嵌入脚本并不等同于设计一门新语言,也用不着什么语法分析的东西,直接用就好了。

乱侃

vc7的编译器cl.exe只有84k,让人难以置信,即使那些大师级程序员们的水平再高,如此复杂的编译器也不可能被压缩到这么大点儿,我用strings看了一下里面的字符串,也没有调用几个函数,分明是一个普通的小程序,这增加了我的疑虑,东翻西看,还真找到了原因。

原来vc7的主要实现都放在了几个dll文件里,cl.exe只是简单的提供一个胶合罢了。bin文件夹下有三个dll文件,c1.dll是C编译器前端,大致有912k,c1xx.dll是C++编译器的前端,2.1M大小,而另外还有一个c2.dll的文件,实现了编译器的后端,有1.78M,前两个估计负责词法语法的分析和中间代码的生成,而后端的c2就是代码的优化和机器代码的输出了。从vc7的头文件里可以看出来它还支持其他的一些cpu,如此只需简单的在后端代码生成部分换一个实现就行了,呵呵,整体结构挺清晰~~~

把C程序写好不容易,C++用习惯之后再来看C,感触颇多,oop并不是C++的特权,重要的是,清晰的结构和设计,c同样可以实现oop,程序的思想存在于programmer的心中。优美的程序是在历尽风霜,对programming的概念和本质深刻认识和理解之后的人的手里写出来的。

路漫漫其修远兮,吾将上下而求索……

学会谦虚

昨天花了一个晚上实现了MD5算法,参考了Ronald Rivest的实现。

最近一直觉得自己写程序上了一个档次,不免飘飘然,但昨天让我意识到自己还差很多,代码看起来略显丑陋,跟unix下那些优雅的源代码没办法比。程序员应该一直抱着谦虚地心态,学无止境。

学习研究,是一个不断进步的过程,得到的东西越多,随之产生的未知也跟着增加,任何时候都不能满足,超越别人之后还要不断超越自己,科学不是为了跟别人竞争而研究的,是为了探索和兴趣,就像牛顿同学所说的,“我只是一个在海边爱玩耍的孩子,偶尔为发现一两个漂亮的石子而雀跃不已”,能力越强应该越懂得谦虚,人一生就是不停的为自己的兴趣而努力,不该有丝毫懈怠。还是孔老先生那句话,生无所息。