essay 浅谈ACM盲区(上)
最近在南邮华为俱乐部做了一次小小的交流,讲的内容是“浅谈ACM盲区”,这里我把主要内容整理出来,如果有不正确的地方欢迎指正。
首先我们来谈谈ACM练习的必要性,正如大家所知,ACM可以:
1.提高编程能力(递归、指针、函数、结构……)
2.学习算法(分治、动态规划、回溯……)
3.锻炼思维
……
但是,不得不对ACMer提醒的是,ACM作为一个竞赛,其具有相当的挑战性,亦具有局限性。如若想全面发展,以下的几个ACM盲区是我们所不能忽视的。
(一)界面友好
即使是在Linux中的开发,也是需要界面友好的,更不用提Windows的界面开发(MFC、Java GUI等)。而在ACM中,一般很少有人去考虑界面的设计以及人机交互。在这里,我做一个简单的提示,可以利用main()函数的参数扩展程序功能。
例如:
(二)编程规范
变量和函数的命名规范,一定要用有意义的字符,而且尽量用英文。不能用无意义的字符,或者用拼音。
例如:
这里我再举三个例子,来说明变量命名的规范性。例子所实现的功能是对一个三位数的百位、十位、个位进行分解。
int x; int v=x%10; int vv=x/10%10; int vvv=x/100; printf("%d %d %d ",v,vv,vvv); int x; int gw=x%10; int sw=x/10%10; int bw=x/100; printf("%d %d %d ",gw,sw,bw); int x; int single=x%10; int decade=x/10%10; int hundred=x/100; printf("%d %d %d ", single,decade,hundred);显然,第三种写法更符合规范,也让人一目了然。
在这里,我在讲一下变量和函数的命名格式,目前主流的写法是采用驼峰式命名。
还有一点非常重要的规范是关于缩进,从逻辑上来讲,我们把相互对应的代码块进行相同的缩进。下面是一个典型的错误范例,其功能是判断一个考分是否及格。
if(score>=0 && score<=100)if(score>=60) printf("pass\n"); else printf("failed\n")很显然,下面的else应该与第二个if配对,在这里缩进,虽然代码是正确无误的,但是不符合规范。正确的写法应该如下所示:
if(score>=0 && score<=100) {if(score>=60) printf("pass\n");else printf("failed\n"); }再下面我讲讲关于注释,一般地,我们尽量用英文来保证兼容性。例如下面的递归的例子:
void solve(int *answer,int step,int currentTotal,int *change,int length,int money) {//answer is a stack array, step is the level of recursion//currentTotal is the current change numbers//change is a const array ([11,17,5,1]), length is the length of const array (4)//money is a const of total money (20)int cnt,i;if(step>length) return;if(currentTotal>currentMin) return;…… }同时,我们可以使用/* */来进行小规模或大规模注释,例如在下面的例子中,我们仅仅希望去除函数中最后一个参数的声明:
void recursion(int *answer,int step/*,int *pcnt*/) { // ……recursion(answer,step+1/*,int *pcnt*/); // (*pcnt)++; }void main() {int *answer=(int*)malloc(20*sizeof(int))/*,cnt=0*/;recursion(answer,0/*,&cnt*/); // printf("cnt=%d\n",cnt); }最后,关于编程规范,我讲讲程序的可移植性、函数封装与模块耦合,一般函数的封装要保证其逻辑性,并将使用者的权限降至最低。
举个简单的例子吧。
这是一个正确的例子,outputArray()函数实现了对数组的输出,其符合逻辑性。而有些人在实现其输出时,将回车符的输出printf(“\n”)写在main()函数中。虽然这样同样能得到正确的结果,但是输出功能应该属于函数outputArray(),放在main()函数中实为不妥,不符合逻辑性。
(三)非实用性方法
ACM中一些“独特”的方法,例如打表法、O(n)排序法等,在今后的工作岗位中,几乎不可能用到。我的建议是,ACM中用用就好,别太当回事即可。
举个打表法的例子:
NOJ 1025 请在从1到某个整数范围中打印出所有的完数来,所谓“完数”是指一个数恰好等于它的所有不同因子之和。其中输入的数字n(1<n<10000)
样例输入
100
5000
样例输出
100: 6 28
5000: 6 28 496
如果不用打表法,很难在规定时间内得出结果。但是,如果打表,则相当简单,下面我给出核心代码。
if(n>=6) printf(" 6"); if(n>=28) printf(" 28"); if(n>=496) printf(" 496"); if(n>=8128) printf(" 8128"); printf("\n");(四)实用性编程
关于实用性编程,我的建议是,在熟练玩转ACM的基础上,至少掌握一个。常见的实用性编程包括但不局限于以下:
Linux下的进程、通信、数据库、GNOME(或Qt)编程
Android 开发
C++ MFC
LAMP Web开发体系(Linux、Apache、MySQL、PHP)
(五)面向对象编程
在ACM中,很少接触到面向对象编程。面向对象是一种对现实世界理解和抽象的方法,是计算机编程技术发展到一定阶段后的产物。对面向对象的介绍,我会在下一个博客中进行简介。同时会举出一个生动的例子,供大家参考。
总结
以上是生活随笔为你收集整理的essay 浅谈ACM盲区(上)的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: Kindle开箱测评以及使用体验
- 下一篇: 北京市谷歌地球高程DEM等高线下载