essay 浅谈ACM盲区(上)
最近在南郵華為俱樂(lè)部做了一次小小的交流,講的內(nèi)容是“淺談ACM盲區(qū)”,這里我把主要內(nèi)容整理出來(lái),如果有不正確的地方歡迎指正。
首先我們來(lái)談?wù)凙CM練習(xí)的必要性,正如大家所知,ACM可以:
1.提高編程能力(遞歸、指針、函數(shù)、結(jié)構(gòu)……)
2.學(xué)習(xí)算法(分治、動(dòng)態(tài)規(guī)劃、回溯……)
3.鍛煉思維
……
但是,不得不對(duì)ACMer提醒的是,ACM作為一個(gè)競(jìng)賽,其具有相當(dāng)?shù)奶魬?zhàn)性,亦具有局限性。如若想全面發(fā)展,以下的幾個(gè)ACM盲區(qū)是我們所不能忽視的。
(一)界面友好
即使是在Linux中的開發(fā),也是需要界面友好的,更不用提Windows的界面開發(fā)(MFC、Java GUI等)。而在ACM中,一般很少有人去考慮界面的設(shè)計(jì)以及人機(jī)交互。在這里,我做一個(gè)簡(jiǎn)單的提示,可以利用main()函數(shù)的參數(shù)擴(kuò)展程序功能。
例如:
(二)編程規(guī)范
變量和函數(shù)的命名規(guī)范,一定要用有意義的字符,而且盡量用英文。不能用無(wú)意義的字符,或者用拼音。
例如:
這里我再舉三個(gè)例子,來(lái)說(shuō)明變量命名的規(guī)范性。例子所實(shí)現(xiàn)的功能是對(duì)一個(gè)三位數(shù)的百位、十位、個(gè)位進(jìn)行分解。
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);顯然,第三種寫法更符合規(guī)范,也讓人一目了然。
在這里,我在講一下變量和函數(shù)的命名格式,目前主流的寫法是采用駝峰式命名。
還有一點(diǎn)非常重要的規(guī)范是關(guān)于縮進(jìn),從邏輯上來(lái)講,我們把相互對(duì)應(yīng)的代碼塊進(jìn)行相同的縮進(jìn)。下面是一個(gè)典型的錯(cuò)誤范例,其功能是判斷一個(gè)考分是否及格。
if(score>=0 && score<=100)if(score>=60) printf("pass\n"); else printf("failed\n")很顯然,下面的else應(yīng)該與第二個(gè)if配對(duì),在這里縮進(jìn),雖然代碼是正確無(wú)誤的,但是不符合規(guī)范。正確的寫法應(yīng)該如下所示:
if(score>=0 && score<=100) {if(score>=60) printf("pass\n");else printf("failed\n"); }再下面我講講關(guān)于注釋,一般地,我們盡量用英文來(lái)保證兼容性。例如下面的遞歸的例子:
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;…… }同時(shí),我們可以使用/* */來(lái)進(jìn)行小規(guī)模或大規(guī)模注釋,例如在下面的例子中,我們僅僅希望去除函數(shù)中最后一個(gè)參數(shù)的聲明:
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); }最后,關(guān)于編程規(guī)范,我講講程序的可移植性、函數(shù)封裝與模塊耦合,一般函數(shù)的封裝要保證其邏輯性,并將使用者的權(quán)限降至最低。
舉個(gè)簡(jiǎn)單的例子吧。
這是一個(gè)正確的例子,outputArray()函數(shù)實(shí)現(xiàn)了對(duì)數(shù)組的輸出,其符合邏輯性。而有些人在實(shí)現(xiàn)其輸出時(shí),將回車符的輸出printf(“\n”)寫在main()函數(shù)中。雖然這樣同樣能得到正確的結(jié)果,但是輸出功能應(yīng)該屬于函數(shù)outputArray(),放在main()函數(shù)中實(shí)為不妥,不符合邏輯性。
(三)非實(shí)用性方法
ACM中一些“獨(dú)特”的方法,例如打表法、O(n)排序法等,在今后的工作崗位中,幾乎不可能用到。我的建議是,ACM中用用就好,別太當(dāng)回事即可。
舉個(gè)打表法的例子:
NOJ 1025 請(qǐng)?jiān)趶?到某個(gè)整數(shù)范圍中打印出所有的完數(shù)來(lái),所謂“完數(shù)”是指一個(gè)數(shù)恰好等于它的所有不同因子之和。其中輸入的數(shù)字n(1<n<10000)
樣例輸入
100
5000
樣例輸出
100: 6 28
5000: 6 28 496
如果不用打表法,很難在規(guī)定時(shí)間內(nèi)得出結(jié)果。但是,如果打表,則相當(dāng)簡(jiǎn)單,下面我給出核心代碼。
if(n>=6) printf(" 6"); if(n>=28) printf(" 28"); if(n>=496) printf(" 496"); if(n>=8128) printf(" 8128"); printf("\n");(四)實(shí)用性編程
關(guān)于實(shí)用性編程,我的建議是,在熟練玩轉(zhuǎn)ACM的基礎(chǔ)上,至少掌握一個(gè)。常見的實(shí)用性編程包括但不局限于以下:
Linux下的進(jìn)程、通信、數(shù)據(jù)庫(kù)、GNOME(或Qt)編程
Android 開發(fā)
C++ MFC
LAMP Web開發(fā)體系(Linux、Apache、MySQL、PHP)
(五)面向?qū)ο缶幊?
在ACM中,很少接觸到面向?qū)ο缶幊獭C嫦驅(qū)ο笫且环N對(duì)現(xiàn)實(shí)世界理解和抽象的方法,是計(jì)算機(jī)編程技術(shù)發(fā)展到一定階段后的產(chǎn)物。對(duì)面向?qū)ο蟮慕榻B,我會(huì)在下一個(gè)博客中進(jìn)行簡(jiǎn)介。同時(shí)會(huì)舉出一個(gè)生動(dòng)的例子,供大家參考。
總結(jié)
以上是生活随笔為你收集整理的essay 浅谈ACM盲区(上)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Kindle开箱测评以及使用体验
- 下一篇: 北京市谷歌地球高程DEM等高线下载