星期六, 八月 30, 2008

程序员偷懒的设计

中文中有三个发“ta“音的人称代词,一个是”他“代表男性,一个是”她“代表女性,一个是”它“代表除了人以外的事物。英文中对应he,she和it。

在许多校内应用中,这些都被“TA”这个拼音形式的词所代替,减少了程序的判断分支,提高了运行速度,而且在表现形式上更加俏皮,深受用户喜爱。

九章算术中的分数比较大小(九章算术系列五)

[一二]今有八分之五,二十五分之十六。问孰多?多几何?
    答曰:二十五分之十六多,多二百分之三。

[一三]又有九分之八,七分之六。问孰多?多几何?
    答曰:九分之八多,多六十三分之二。

[一四]又有二十一分之八,五十分之十七。问孰多?多几何?
    答曰:二十一分之八多,多一千五十分之四十三。
    课分术曰:母互乘子,以少减多,余为实,母相乘为法,实如法而一,即相多也。


这部分方法和分数减法相同,只是在最后有一个比较的过程。

辗转相减法求最大公约数要点

辗转相减法在《九章算术》中有所论述

方法如下:
1 用2对分子分母约分,记录约分次数count;
2 如果分子或分母出现奇数,则转到3;
3 分子分母中较大的为a,较小的为b;
4 c = a - b;
5 若c与b不相等,则c与b中较大的为a,较小的为b,回到4;相等则到6;
6 若count为0,则result = c;不为0则c乘以2的count次方的积赋给result;
7 result即为a与b的最大公约数。

这里有一点需要注意:
当a与b相等时,这个算法不能正确处理,所以应保证a与b不相等。但是如果使用辗转相除(欧几里得算法)就没有这个问题。

代码及测试如下:

substraction.c 描述了辗转相减法
====================================================================
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

//#define _DEBUG_ 1

void print_usage()
{
printf("Usage: rotate_substraction <num1> <num2>");
printf("\n");
}

int rotate_substraction(int num1, int num2, int odd_time)
{
// equal number is itself
if (num1 == num2) {
return num2;
}
#ifdef _DEBUG_
printf("Num1 is : %d\n", num1);
printf("Num2 is : %d\n", num2);
#endif
// half
while (num1 % 2 == 0 && num2 % 2 == 0) {
num1 >>= 1;
num2 >>= 1;
odd_time++;
}

// substrcation
int sub = num1 - num2;
if (sub == num2) {
if (odd_time == 0) {
return sub;
} else {
return sub * pow(2, odd_time);
}
} else {
return rotate_substraction(
sub > num2 ? sub : num2,
sub < num2 ? sub : num2,
odd_time
);
}
}

int main(int argc, char **argv)
{
if (argc < 3) {
print_usage();
return -1;
}

int num1 = atoi(argv[1]);
int num2 = atoi(argv[2]);

printf("[%d, %d]Equal Number is : %d\n", num1, num2,
rotate_substraction(
num1 > num2 ? num1 : num2,
num1 < num2 ? num1 : num2,
0
));

return 0;
}

devision.c 描述了辗转相除法(欧几里得算法)
====================================================================
#include <stdio.h>
#include <stdlib.h>

//#define _DEBUG_ 1

void print_usage()
{
printf("rotate_devision <num1> <num2>");
printf("\n");
}

int rotate_devision(int num1, int num2)
{
#ifdef _DEBUG_
printf("Num1 is : %d\n", num1);
printf("Num2 is : %d\n", num2);
#endif

if (num1 % num2 == 0) {
return num2;
}

int dev = num1 % num2;

return rotate_devision(
dev > num2 ? dev : num2,
dev < num2 ? dev : num2
);
}

int main(int argc, char **argv)
{
if (argc < 3) {
print_usage();
return -1;
}

int num1 = atoi(argv[1]);
int num2 = atoi(argv[2]);

printf("[%d, %d]Equal Number is : %d\n", num1, num2,
rotate_devision(
num1 > num2 ? num1 : num2,
num1 < num2 ? num1 : num2
));

return 0;
}

测试bash脚本
====================================================================
#!/bin/sh

gcc -lm -o substraction substraction.c
gcc -o devision devision.c

for i in $(seq 1 100); do
./substraction 100 $i >> sub_result
./devision 100 $i >> dev_result
diff -i sub_result dev_result > result
cat result
rm *_result
done

我测试了1到10000和10000的最大公约数,两种算法所得结果一致。

九章算术中的分数减法(九章算术系列四)

[一0]今有九分之八,减其五分之一。问余几何?
    答曰:四十五分之三十一。

[一一]又有四分之三,减其三分之一。问余几何?
    答曰:十二分之五。
    减分术曰:母互乘子,以少减多,余为实,母相乘为法,实如法而一。

母互乘子,以少减多,余为实,母相乘为法,实如法而一。

交叉相乘,分子大减小,差为分子,分母相乘做分母

星期五, 八月 29, 2008

九章算术中的分数加法(九章算术系列三)

[七]今有三分之一,五分之二。问合之得几何?
   答曰:十五分之十一。

[八]又有三分之二,七分之四,九分之五。问合之得几何?
   答曰:得一、六十三分之五十。

[九]又有二分之一,三分之二,四分之三,五分之四。问合之得几何?
   答曰:得二、六十分之四十三。
   合分术曰:母互乘子,并以为实,母相乘为法,实如法而一。不满法者,
以法命之。其母同者,直相从之。

母互乘子就是交叉相乘,这里的”实“是分子,”法“是分母。
并以为实,是说乘积作为分子。
母相乘为法,分母相乘作为分母。
实如法而一,用分母除分子,得数为整数部分。
不满法者,以法命之,就是分子比分母小的时候,保留原样。
其母同者,直相从之。 分母相同可以直接运算。

这里有通分的方法,但是没有涉及最小公倍数,而是使用分母直接相乘的更加一般的方法。

星期四, 八月 28, 2008

九章算术中的分数(九章算术系列二)

[五]今有十八分之十二。问约之得几何?

   答曰:三分之二。

[六]又有九十一分之四十九。问约之得几何?
   答曰:十三分之七。
   约分术曰:可半者半之,不可半者,副置分母子之数,以少减多,更相减损,求其等也。以等数约之。


例五说明了可半者半之,就是用2作为约数,化简分数。

例六说明了不可半者这种情况,解题思路在后半部分。


副置分母子之数,以少减多,更相减损,求其等也。以等数约之。

就是用分母和分子为一组,大减小,差和上次较小的数为一组,大减小,如此交替相减,直到得数和减数相同,这个数就是等数,也就是最大公约数。


原理和辗转相除就最大公约数的欧几里得算法在理论上是相通的。


请看贴的同学想两个数求证下我的翻译。


感谢传东和老徐给出的意见。

星期三, 八月 27, 2008

九章算术中的矩形面积计算(九章算术系列一)

locate:九章算术卷一 方田

source:

[一]今有田广十五步,从十六步。问为田几何?
   答曰:一亩。

[二]又有田广十二步,从十四步。问为田几何?
   答曰:一百六十八步。
   方田术曰:广从步数相乘得积步。
   以亩法二百四十步除之,即亩数。百亩为一顷。

[三]今有田广一里,从一里。问为田几何?
   答曰:三顷七十五亩。

[四]又有田广二里,从三里。问为田几何?
   答曰:二十二顷五十亩。
   里田术曰:广从里数相乘得积里。以三百七十五乘之,即亩数。


这里涉及矩形面积、乘法计算、单位换算。

星期四, 八月 21, 2008

从番茄花园作者被抓说起

番茄花园版XP,别说你没听说过,如果你真没听说过,那就雷死我了(尤其是MM)。

说实话我对于这种注重主题和界面的系统没有什么好感,所以一直很厌恶Vista。记得在一本书上看过,CPU和内存是给用户用的,不是给程序员用的!大意是要求程序员追求算法和效率。不过这句话用在 Vista上同样合适,CPU最好800核的,同时主板最好支持4个CPU插槽,内存最好和现在的硬盘一样容量。由于对于M$的厌恶,有点激动。而且逢多必少,在界面上丰富了,其他功能就会缩水,毕竟一张CD就是700M的地方,装了这个就放不上那个,鱼与熊掌不可兼得,系统其他的部分会少很多东西。到处找缺少的DLL,对于做开发是灾难。

回来看番茄花园,我觉得微软在中国计算机产业的初期还是间接作出了贡献的。为什么有贡献呢?没有微软就会造成Apple在个人计算机的垄断,那样现在你也只能看着1W多的计算机望而却步,甚至会更贵。那又为什么是间接贡献呢?就是因为微软不是甘心情愿让我们用盗版的,它也想打击,但是那时我们国家人民生活水平和全民素质都相较现在要低。如果让我们用正版,那么现在我也不会用计算机在这写文章,我们的信息化进程也不会这么快。所以说微软是间接帮助了我们发展计算机产业。

盗版是一把双刃剑,它能在某方面帮助我们,也可以毁掉我们的另一些东西。

盗版扼杀了民族软件产业

由于盗版猖獗,国外优秀的软件几乎没有在中国赚到什么钱,受害者也包括微软。而在互联网不发达的计算机产业初期,大多软件生产商都是靠卖掉自己软件的CD拷贝谋生。一个软件开发生产企业,辛辛苦苦开发出来优秀的软件,不出一周就有破解版出来,您想他能赚到钱么?我们民族的软件产业从何崛起,我们只能沦为软件生产基地,而不是研发基地,因为我们的国民并不买帐。

盗版让我们的版权意识淡漠

由于随手可以买到4-6元的盘,我们从来就不知道什么license,cd-key的真正含义,而只是把这些东西看作我们使用软件的绊脚石。我们大骂微软和其他大的软件生产商,这简直是贼喊捉贼!而且这种版权意识的淡漠迅速扩张,影响到我们的电影,出版甚至学术领域,这真的很可怕。

盗版偷走了我们的创新意识

由于长期信手拈来的盗版软件,我们的创新意识一点点丧失,我们从来不用考虑没有软件用或者用不起软件,甚至有些人开始追求软件的版本,总是用最新的。大家可以上网查查你现在机器里收费软件的价格,微软的计算器是作为windows赠品的,这个不用花钱,不过你可以用这个算算你机器里收费软件的总价,估计大家都挺有钱的。由于没有经济上的逼迫,我们没有了创新的动力。没有枪,没有炮,只等盗版送上前!

我对于盗版的态度想必大家也都看出来了,能一棍子打死绝不让他留一口气!

网上有很多人认为我们使用盗版微软也没招对付我们,我们就是让他从我们手里赚不到一分钱。如果你有些计算机知识,你应该知道那只是微软不愿意跟我们费劲而已。从番茄花园作者被捕,还有前些日子的珊瑚虫QQ事件可以看出,我们国家对于知识产权保护的力度在加大。现在我们只有两条路可以选择:一是抓紧时间赚钱为你的软件买单;二是学学别的不要钱的操作系统。这都是为微软痛下杀手作准备,到那时至少你不会因为看不到我的博客而着急。

星期一, 八月 18, 2008

我对刘翔退赛的看法

上午一直等刘翔的预赛,突然QQ弹出新闻说刘翔退赛了,随即到电视那求证,果然是这样。

网上立场基本分两派,大家可以慢慢去看。

我不想对于刘翔的退出说太多,也不想讨论他是不是因为商业利益和名声作出决定。相反,我比较关注观众的表现。

刘翔的退出如果不是伤病,而是另有原因的话,我想那最大的原因是观众。

记得奥运会的首金风波吗?杜丽就是由于压力过大而没有按照大家的期望夺得金牌。

国 人的期望也不能说成是运动员夺金的障碍,毕竟这些都是有原因的,中国做了百年的奥运梦终于变成了现实,而且观众给运动员加油助威本身也并没有什么不妥之 处。另一方面,这届奥运会在宣传和媒体工作上做足了文章,央视更是全员上岗,感觉转播比赛时候频道都有点不够用。媒体的宣传以及导向作用得以充分发挥,但 是引导方向未免有些不妥。

比如赛前采访运动员的家人,运动员的家人说大了怕自己的亲人辜负全国人民的期望,而过于谦虚又不免显得信心不 足。况且大多数运动员生于农村,父母亲人都是淳朴的农民,也不会弄些外交辞令来和媒体打太极。种种情况造成了这类新闻中,受访者“麻杆打狼两头怕”,而采 访者找不到要挖掘的新闻点的尴尬局面。

央视在刘翔退场后报道现场观众随着刘翔一起纷纷退场,我们想看自己运动员的优异表现固然重要,但在现场的您除了期待运动员挑战极限后的辉煌一刻,是不是也应该做好为运动员的失败鼓掌的心理准备呢?至少您的门票是花钱买的,您这么就走想表达些什么呢?

再 次就是项目上的原因,杜丽所在的射击队是中国的传统优势项目。许海峰就是搞射击的,可想而知中国的射击队是如何的强了。杜丽在首金失手后,她后面还有项 目,她还有获得大家宽容的原因。同时,中国射击队在本届奥运会上的出色表现,也可以用夺金的狂潮把杜丽从大家脑中迅速冲得干干净净。而刘翔的处境完全不 同,在短跑甚至整个田径项目上,大家把目光都投向了他。一个人肩负的太多,压力也就大得多,就越容易崩溃。

如果刘翔是因为伤病退出,这我表示同情;如果像某些人所说由于怯懦,我也表示理解。

刘翔是创业容易守业难,他身上的包袱不像当年那么轻松了。

星期日, 八月 17, 2008

在wiki的支援下学习

最初认识wiki的时候是把它作为大字典和百科全书使用的,遇到不明白的名词就用键盘翻看一下,今天要找做课的相关资料突然发现了一个词条:单位元

以下是单位元的中文wiki解释

http://zh.wikipedia.org/w/index.php?title=%E5%8D%95%E4%BD%8D%E5%85%83&variant=zh-cn

而后我从链接查看了二元运算,加法逆元和逆元素,原来他们的定义都是互相联系的。数学好的不要啐我,这个关系上了四年大学都没搞清楚,当时只是死背性质,哪知其中的关系。知识的联系是十分关键的,知道了这些关系,相信一个文科学生也能看明白什么叫逆元素。

中国现今的义务教育是把知识根据学生的认知程度分成了几个部分去教授,而教师往往就事论事,很少帮助学生梳理知识的关系。

网络上的wiki的优势在于它在解释一个词条的时候往往给出用到名词的超链接,这样你如果看不懂当前的词条,可以用鼠标一挖到底,找到这个概念的根源,而后在反向回到你最初要查找的词条,层层理解,级级攻破,建立系统的知识体系结构。

这个过程很像计算机算法术语中的递归,果然是大道皆同啊。

不过现在wiki的表现形式还比较单一,属于文字和图表阶段,如果能加上彩色的照片,甚至视频。这个表现力很可能成为未来的一种自学或者教学的方式。

星期日, 八月 10, 2008

Beijing 2008 Olympic Game Opening Ceremony 5

Posted by Picasa

Beijing 2008 Olympic Game Opening Ceremony 4




Posted by Picasa

Beijing 2008 Olympic Game Opening Ceremony 3




Posted by Picasa

Beijing 2008 Olympic Game Opening Ceremony 2




Posted by Picasa

Beijing 2008 Olympic Game Opening Ceremony 1




Posted by Picasa

星期一, 八月 04, 2008

卫津路上迎火炬

Posted by Picasa

星期日, 八月 03, 2008

长春雕塑公园




Posted by Picasa