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开箱测评以及使用体验
- 下一篇: 深度学习入门书籍和资源