标签 程序员 下的文章

算法描述中的'Pseudocode Conventions'

Pseudocode,即伪码,它常常用来描述一个算法,目的是能使被描述的算法能够容易的以任何一种计算机程序语言实现。’Pseudocode Conventions’可以理解为’伪码约定’,既然是’约定’那就并非强制性的标准。但是在专业的有关算法的文献和资料中,其相关内容多符合这些’Pseudocode Conventions’。如果你是一个想学习和钻研算法的人,那么建议你熟悉这些’Conventions’,俗话说:’磨刀不误砍柴工’吗!

‘Pseudocode Conventions’应该说也是有多种多样的,但是随着这么多年的积累和进化,渐渐的一些’Conventions’退出了人们的视线,此时你在一些重要的图书典籍上能看到的大概就是被人们广泛接受的一种’Convention’了。这里介绍一种比较常用的’Pseudocode Convention’,这种’Convention’在MIT Press出版的’Introduction to Algorithms 2nd‘中被广泛采用,在国内的一些算法书籍中也是’屡见不鲜’。

介绍’Pseudocode Conventions’其实与介绍一种程序设计语言的语法相似,看多了就会产生厌烦,这里先给出一个例子,让大家有个感性认识,找到一种新鲜感。^_^

这个例子源于’Introduction to Algorithms’一书中的那个著名的’Insertion-Sort’:
Insertion-Sort(A) △ A[1..n]
    for j <- 2 to length[A]
        do key <- A[j]
            △ Insert A[j] into the sorted sequence A[1..j-1].
            i <- j-1
            while i > 0 and A[i] > key
                do A[i+1] <- A[i]
                    i <- i-1
            A[i+1] <- key

对应上面的例子,下面是对该’Convention’的一些阐述条款:

1、每个指令占据一行,指令结束或者说行尾无任何符号。
2、利用’缩进(Indentation)’表示程序的块结构(Block Structure)。
3、符号’△’表示该行其后面的内容为注释。
4、’i <- j’为赋值语句,表示将j的值赋给i;而’i <- j <- e’这样的多重赋值形式则等价于’i <- e’, ‘j <- e’。
5、变量无需声明;一般情况下变量局限于某一特定的Procedure,除非有显式说明我们才使用全局变量。
6、数组A通过A[index]方式访问到数组内元素的值。
7、条件判断语句格式如下:
if (Condition1)
    then [ Block 1 ]
    else if (Condition2)
           then [ Block 2 ]
           else [ Block 3 ] 

8、支持三种循环语句:while、for、repeat … until。’for t <- 0 to n’表示 t范围为[0, n)。
9、复合数据用对象(Object)来表示。对象由属性(Attribute)和域(Field)构成。域的存取是由域名后接由方括号括住的对象名表示,如上面李子中的length[A],数组A被看成为一个Object,其域有length,表示数组中元素的个数,即length[A]。用于表示一个数组或对象的变量被看作是指向表示数组或对象的数据的一个指针。对于某个对象x的所有域f,赋值y<-x就使f[y]=f[x],换言之,在赋值y<-x后,x和y指向同一个对象。有时一个指针不指向任何对象,这时我们赋给它NIL。
10、参数传递方式为’值传递’方式,被调用的过程拥有自己的参数拷贝,被调用过程对参数的修改是不能被调用者看到的。当传递一个对象时,只是拷贝指向该对象的指针,而不拷贝其各个域。
11、布尔运算符’and’和’or’都是’short circuiting’的。如计算表达式’x and y’,如果x为FALSE,那么整个表达式就为FALSE,我们不再计算y了。

OK,罗列了11项,照比C这类的高级语言,这种’语法’显然简单的多,更易理解。以后要做的就是尽量在进行算法描述的时候使用这种’Pseudocode Convention’,毕竟熟才能生巧!

你提供默认选项了吗

五一期间到姥姥家串门儿,自然午饭要在那吃,可中午做饭时听姥姥抱怨新买的电饭煲做饭时间太长而且还夹生,我好奇的走了过去想看看究竟,电饭煲的确是新买不久的,而且是美的的,我心想大牌厂商应该不会有这样的质量问题呀,一定是姥姥使用上的问题。仔细看了看控制板,果然不出所料,电饭煲的’功能选择’键停在了功能档的中央,既不是左边的’煮饭’也不是右边的’煲粥’,遂告诉姥姥以后煮饭要把功能选择调到’煮饭’档。

吃完午饭,闲来无事,便又想起这件事来,联系到Keso写过的一篇叫’默认的力量‘的文章,自己又有了些新想法。当Keso那篇文章说的是IE用’默认的力量’打败了’Netscape’,其中总结的一个潜规则就是’用户都是无知者’,’无知者’一方面可能没有能力去挖掘你的工具提供的诸多强大的功能,另一方面则是少有人愿意为挖掘出那些强大的功能而付出劳动,能用就好,最理想的就是’拿来即用’。这也好比一台理想的电视机,从商店买回家里,插上电源,按下电源开关,全国各个电视台就都能在电视上看到,而无需去人工搜索设定电视频道。这样的情形在很多场合都能见到,在软件开发中也不例外。

自己曾经在一个项目中提供了这样一组宏,其目的就是为了利用编译开关来选择程序输出的调试日志级别,比如level 1级别的日志只是输出某些最重要的调试信息,level 3级别的则是输出所有调试信息。当时没有多想就在一个头文件中写下了如下的代码:
/*
 * 代码片断1
 */
#ifdef _DEBUG_LEVEL1

#define MY_TRACE_L1(name, stat) TRACE(name, stat)
#define MY_TRACE_L2(name, stat) {}
#define MY_TRACE_L3(name, stat) {}

#endif /* _DEBUG_LEVEL1 */

#ifdef _DEBUG_LEVEL2

#define MY_TRACE_L1(name, stat) TRACE(name, stat)
#define MY_TRACE_L2(name, stat) TRACE(name, stat)
#define MY_TRACE_L3(name, stat) {}

#ifdef _DEBUG_LEVEL3

#define MY_TRACE_L1(name, stat) TRACE(name, stat)
#define MY_TRACE_L2(name, stat) TRACE(name, stat)
#define MY_TRACE_L3(name, stat) TRACE(name, stat)

不久一同项目组的哥们发来mail说程序编译不过去了,我迅速查了一下,发现在Makefile中没有定义任何DEBUG LEVEL宏,再看一下上面的代码你就会知道如果没有定义任何DEBUG LEVEL宏,那么用在程序代码中的MY_TRACE_Ln就是’undefined symbols’,程序自然不能编译通过。解决的方法很简单:添加一个DEBUG LEVEL宏,不过这样并不是一劳永逸的做法。正如我们上面所言,’用户都是无知的’,使用该程序的人最愿意看到的就是敲入’make’,马上得到可执行程序,而不是先添加一个宏定义后再make。最后我提供了一个默认的DEBUG LEVEL,解决方法如下:
/*
 * 代码片断2
 */
#if !defined(_DEBUG_LEVEL1) && !defined(_DEBUG_LEVEL2) && !defined(_DEBUG_LEVEL3)
#define _DEBUG_LEVEL1
#endif
把’代码片断2′放到’代码片断1′的前面,这样即使用户没有定义任何DEBUG LEVEL宏,程序仍然可以顺利通过编译。这段小插曲提醒我们时刻想着提供一个’默认的选项’,有些时候它事关重大,不能小觑它的力量。

仅仅提供一个’默认选项’就够了么?我们再回到前面的那个’美的’电饭煲的设计上。从功能上该电饭煲提供了两种功能’煮饭’和’煲粥’,但是它好像并未提供默认的选项,而是将’功能选择’键放在了功能档的中央。也许有些人会说这可能就是电饭煲提供的默认的选项呢,也许这个中间档是出于安全考虑呢。但是我要说即使它是默认选项,它也有误导的作用,不了解它的人会认为这样就可以煮饭了,我姥姥就是这么想的。没错儿,这里我要说的就是’谨慎选择默认项,不要误导使用者’。这里我没有很好的软件开发中的例子来说明,似乎少了些说服力,不过通过这个电饭煲的例子你也可以悟到一些东西。其实如果我是电饭煲的设计者,我是不会允许将’功能选择’键放在了功能档的中央的,要么放在’煮饭’档要么放在’煲粥’档。^_^

你在开发中提供默认选项了么,如果还没有的话,那就该好好想想是否是时候添加一个没有误导作用的默认选项了。

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! Go语言第一课 Go语言精进之路1 Go语言精进之路2 Go语言编程指南
商务合作请联系bigwhite.cn AT aliyun.com

欢迎使用邮件订阅我的博客

输入邮箱订阅本站,只要有新文章发布,就会第一时间发送邮件通知你哦!

这里是 Tony Bai的个人Blog,欢迎访问、订阅和留言! 订阅Feed请点击上面图片

如果您觉得这里的文章对您有帮助,请扫描上方二维码进行捐赠 ,加油后的Tony Bai将会为您呈现更多精彩的文章,谢谢!

如果您希望通过微信捐赠,请用微信客户端扫描下方赞赏码:

如果您希望通过比特币或以太币捐赠,可以扫描下方二维码:

比特币:

以太币:

如果您喜欢通过微信浏览本站内容,可以扫描下方二维码,订阅本站官方微信订阅号“iamtonybai”;点击二维码,可直达本人官方微博主页^_^:
本站Powered by Digital Ocean VPS。
选择Digital Ocean VPS主机,即可获得10美元现金充值,可 免费使用两个月哟! 著名主机提供商Linode 10$优惠码:linode10,在 这里注册即可免费获 得。阿里云推荐码: 1WFZ0V立享9折!


View Tony Bai's profile on LinkedIn
DigitalOcean Referral Badge

文章

评论

  • 正在加载...

分类

标签

归档



View My Stats