欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

essay 浅谈ACM盲区(上)

发布时间:2023/12/20 49 豆豆
生活随笔 收集整理的这篇文章主要介绍了 essay 浅谈ACM盲区(上) 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

最近在南邮华为俱乐部做了一次小小的交流,讲的内容是“浅谈ACM盲区”,这里我把主要内容整理出来,如果有不正确的地方欢迎指正。
首先我们来谈谈ACM练习的必要性,正如大家所知,ACM可以:
1.提高编程能力(递归、指针、函数、结构……)
2.学习算法(分治、动态规划、回溯……)
3.锻炼思维
……
但是,不得不对ACMer提醒的是,ACM作为一个竞赛,其具有相当的挑战性,亦具有局限性。如若想全面发展,以下的几个ACM盲区是我们所不能忽视的。
(一)界面友好
即使是在Linux中的开发,也是需要界面友好的,更不用提Windows的界面开发(MFC、Java GUI等)。而在ACM中,一般很少有人去考虑界面的设计以及人机交互。在这里,我做一个简单的提示,可以利用main()函数的参数扩展程序功能。
例如:

void main (int arg0, char** arg1) {if (arg0 == 2 && strcmp (arg1[1], "-help") == 0){showHelpInformation();}//…… }

(二)编程规范
变量和函数的命名规范,一定要用有意义的字符,而且尽量用英文。不能用无意义的字符,或者用拼音。
例如:

double getVariance(int *array,int length); void encrypt(char *plain,char *key,char cipher); double stdIcValue,minIcValue;

这里我再举三个例子,来说明变量命名的规范性。例子所实现的功能是对一个三位数的百位、十位、个位进行分解。

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);

显然,第三种写法更符合规范,也让人一目了然。
在这里,我在讲一下变量和函数的命名格式,目前主流的写法是采用驼峰式命名。

//变量:开头字母小写 stdIcValue,textField//函数:开头字母小写 double getVariance(int *array,int length) View findViewById(int id) void setOnClickListener(OnClickListener l)//类、结构: 开头字母大写 SQLiteOpenHelper LocationListener//常量: 全大写 #define INFTY 99999 const int INFTY=99999; final int INFTY=99999;

还有一点非常重要的规范是关于缩进,从逻辑上来讲,我们把相互对应的代码块进行相同的缩进。下面是一个典型的错误范例,其功能是判断一个考分是否及格。

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); }

最后,关于编程规范,我讲讲程序的可移植性、函数封装与模块耦合,一般函数的封装要保证其逻辑性,并将使用者的权限降至最低。
举个简单的例子吧。

void outputArray(int *array,int length) {int i;for(i=0;i<length;i++)printf("%d ",array[i]);printf("\n"); } void main() {int array[]={1,2,3,4,5};int length=sizeof(array)/sizeof(int);outputArray(array,length); }

这是一个正确的例子,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盲区(上)的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。