江蘇省單招c語言技能編程詳解
今日無事,水篇教程
閱覽了很多道江蘇單招的C語言編程題,又看了看各校同學們的編程情況,突覺很多同學編程時候都沒有一個完整的思路,特此寫此文獻給有需要的同學
算法
編程最重要的就是算法,這關系到你的代碼是否清晰明了,當然我們單招班的同學不需要在意那么多,能解題的算法就是好算法,看了看,單招的學習范圍與試題,其實內(nèi)容是非常少的,理論上來說應該能挺輕松的學習與掌握
在此我就提出幾個我認為較合適的算法:
一、賦值法(進階)
曾經(jīng)看到有同學直接將答案的值賦值給相應的數(shù)組或變量并返回一個具體的值來獲取滿分,很顯然,這方法不可取,因為你技能高考的時候批卷老師會手動點開看你是不是直接賦值,雖然該方法不能用,但是我們能借用該方法的思想來進行一些取巧,即:面向結(jié)果編程,你知道答案,你也知道題目具體要輸入數(shù)組 的格式,那么我們不一定需要做一些不必要的判斷,而可以選擇直接賦值(僅適用于題目數(shù)組或數(shù)值格式固定的情況),我們直接看例子
賦值法(例一)
字符串str中存放了一串表格數(shù)據(jù),其中字母表示列,數(shù)字表示行
str=“ A5:D13 E23:G26 B6:D7 R1:T10”;
函數(shù)hl(int a[][2],char str[])的作用是:把表格行列數(shù)量存入a數(shù)組中,其中行數(shù)存入第0列,
列數(shù)存入第1列,函數(shù)返回表格數(shù)量
思路:因題目格式固定,第一個固定為列坐標,列坐標后固定為行坐標,之后為‘:’,列坐標,行坐標,由此格式可一次完成賦值操作,具體如下,可以先自己思考一下該怎么寫
int hl(int a[][2],char str[]) {int i,j,h1,h2,l1,l2,n=0;for(i=0;str[i];i++){if(isalpha(s[i])/*判斷s[i]是否為英文字母 該處也可寫isupper()判斷是否為大寫字母 如果禁用函數(shù),可寫(s[i]>='A'&&s[i]<='Z')*/{l1=s[i];//確定列1的坐標,注意這邊l1存放的是第一個英文字母的ascll碼i++;//由題可知,字母后是數(shù)字h1=0;while(isdigit(s[i]))h1=h1*10+s[i++]-48;//h1存放第一個行坐標,運行完成后s[i]值指向‘:’i++;//使i的值指向第二個英文字母l2=s[i++];//將第二列的值放入l2中,并使i指向第二行所對應的數(shù)字h2=0;while(isdigit(s[i]))h2=h2*10+s[i++]-48;//h2存放第二個行坐標//現(xiàn)在數(shù)值取完了,那就進行賦值a[n][0]=l2-l1+1;a[n++][1]=h2-h1+1;//n是用來計數(shù)的變量}} return n;//返回表格數(shù)量 }賦值法(例二)
上文說過,賦值法只能用于固定格式的題目中,那么什么是固定的格式呢,是只能像例一那樣一板一眼的格式嗎,其實不然,視角不能狹隘,思想需要開闊,我們來看這么一道題
函數(shù) int fun(char s[],double a[])功能為:將字符串s中提取所有的正負號、數(shù)字和小數(shù)點等組成的子串轉(zhuǎn)換為實數(shù)存儲到數(shù)組a中,函數(shù)返回提取的實數(shù)個數(shù)。
字符串s為"abc34.5y-3.8-.03hh-a125-0.55ASgf-3#"
程序需要提取的實數(shù)為:
-0.5500 -0.0300 -3.8000 -3.0000 34.5000 125.0000
大家認為,這東西的格式固定嗎,其實也是固定的,這是所謂的多格式結(jié)構(gòu)
由此圖可以看出,這其中的數(shù)值只需做三種判定
負號
小數(shù)點+數(shù)字
數(shù)字
負號決定數(shù)值的正負,小數(shù)點+數(shù)字決定小數(shù)部分,數(shù)字決定整數(shù)部分
將之賦值給要求數(shù)組,這稱為賦值法
具體如下:
int fun(char s[],double a[]) {/**********Program**********/int i,j=0,k,f=1;double s1=0,s2=0;//f為符號部分,s1是整數(shù)部分,s2是小數(shù)部分for(i=0; s[i]; i++) {if(s[i]=='-'&&(s[i+1]=='.'||isdigit(s[i+1])))//第一種情況:s[i]是負號且后面跟著的是數(shù)字或小數(shù)點f=-1;if(isdigit(s[i])) { //第二種情況:s[i]是數(shù)字s1=0;while(isdigit(s[i]))s1=s1*10+s[i++]-48;i--;//上面的循環(huán)i++會多加一次,將之減去}if(s[i]=='.'&&isdigit(s[i+1])) { //第三種情況:s[i]是小數(shù)點且后面是數(shù)字s2=0;k=1;i++;while(isdigit(s[i]))s2=s2+(s[i++]-48)*pow(0.1,k++);i--;}if(isdigit(s[i])&&((s[i+1]!='.'&&s1!=0)||s2!=0)) { //數(shù)值提取完成的情況,將之賦值給數(shù)組,自己數(shù)值帶進去試試就懂了a[j++]=f*(s1+s2);s1=0;s2=0;f=1;}}return j;/********** End **********/ }二、分解法
所謂分解法,顧名思義,就是把題目拆分,使之成為我們所熟悉的各種程序段,我們把這些程序段拼起來,那么一段程序也就寫好了
我研究了幾套試題,得出了以下幾個常用程序段:
矩陣轉(zhuǎn)置
進制轉(zhuǎn)換
在字符串中讀取數(shù)據(jù)
數(shù)值查詢
左移右移
計數(shù)
排序
刪除
插入
求最大公約數(shù)(最小公倍數(shù))
求逆序數(shù)
判斷質(zhì)數(shù)(互質(zhì)數(shù))
程序段具體寫法請自行去下個章節(jié)查看
關鍵要點:逐句分析,將困難的問題簡單化
如:
程序首先取出字符數(shù)組s中的連續(xù)數(shù)字字符子串,這是字符串中取數(shù)值
將n個浮點數(shù)按絕對值大小進行排序,排序的變種,追本溯源,還是排序
分解法(例一)
/*-------------------------------------------------------------------------【程序設計】
---------------------------------------------------------------------------
題目:主函數(shù)main()中的字符數(shù)組s為測試數(shù)據(jù),程序首先取出字符數(shù)組s中的連續(xù)數(shù)
字字符子串,構(gòu)成若干個整數(shù),保存到t數(shù)組中,然后找出數(shù)組中的所有素數(shù),
并將素數(shù)順序存放到數(shù)組的后部。
編寫程序:
1.編寫int abstract(char s[],int t[])函數(shù)。取出字符數(shù)組s中的連續(xù)數(shù)
字字符子串,構(gòu)成若干個整數(shù),保存到數(shù)組t中。函數(shù)返回整數(shù)個數(shù)。
2.編寫函數(shù)void move( int t[], int n),找到t數(shù)組中的所有素數(shù),并將
該數(shù)組中的所有素數(shù)順序移到數(shù)組的后面,素數(shù)間的相對位置不變。
例如:字符數(shù)組s中的數(shù)據(jù)為"yu11asd18**6$abc3jui17t*r33t10?qwe31nm19jj21da"
則數(shù)組t中元素為:11 18 6 3 17 33 10 31 19 21
程序運行結(jié)果:18 6 33 10 21 11 3 17 31 19
--------------------------------------------------------------------------
注意:請勿改動主函數(shù)main()中的任何語句。
-------------------------------------------------------------------------*/
看到這種題目啊就很明顯
第一個函數(shù)abstract,里面包含的程序段為字符串中讀取數(shù)據(jù)與計數(shù)
第二個函數(shù)move,里面包含的程序段為判斷質(zhì)數(shù)與左右移
具體寫法如下:
#include<stdio.h> #include<stdlib.h> #include<ctype.h> #include<math.h>int abstract(char s[],int t[]) { /**********Program**********/int i=0,n=0,sum;while(s[i]){ if(isdigit(s[i])){ sum=0;while(isdigit(s[i]))sum=sum*10+s[i++]-'0';//從字符串中取數(shù)值固定寫法t[n++]=sum;//n數(shù)值為t數(shù)組中元素個數(shù)} else i++;}return n; /********** End **********/ } void move( int t[], int n) { /**********Program**********/int i,j,m,temp,k;m=n;for(i=0;i<n;i++){for(j=2;j<t[i];j++)if(t[i]%j==0)//判斷是否為質(zhì)數(shù)break;if(j==t[i]){ temp=t[i];for(k=i;k<m-1;k++)t[k]=t[k+1];t[k]=temp;//左移i--;n--;}/********** End **********/ } int main() {char s[]={"yu11asd18**6$abc3jui17t*r33t10?qwe31nm19jj21da"};int t[20],i,n;FILE *fp;if((fp=fopen("data.dat","w"))==NULL){printf("File open error\n");exit(0);}n=abstract(s,t);move(t,n);for(i=0;i<n;i++){printf("%d ",t[i]);fprintf(fp,"%d ",t[i]);}fclose(fp);return 0; }三、搭建法
逐句讀題,逐字解題,此為搭建
首先地基,也就是定義得完整,全面,考慮要不要用到各種變量,即數(shù)組字符串,善用數(shù)組字符串會對編程有很大幫助
根據(jù)題目一步步把答案寫出來,你不一定要把所有過程寫在一個循環(huán),你甚至可以選擇把循環(huán)拆出來一次次執(zhí)行,甚至將部分結(jié)果存入靜態(tài),再用遞歸來解決
像搭樓一樣一層層蓋上去
總的概括:搭建法就是用基本程序段的疊加與基本函數(shù)的使用來湊出一個完整的答案,無論多長,答案對就行
四、推演法
分解題目成小塊,可以用樹形結(jié)構(gòu)在紙上先把題目拆出來,一步步看應該怎么做,這就是推演,這方法很抽象,但是也很有效,但具體過程需要自己去悟
五、函數(shù)法
編程題的函數(shù)庫很全,里面有很多很好用的函數(shù),直接拿來用一用,省時還省力,下面就列舉一些不常用,但又很好用的函數(shù)(建議背誦)
紅字為本來就應掌握的部分,主要還是黑字的內(nèi)容,如果紅字的都不認識,趕緊背誦
tip: 如*int寫法為指針類型,通俗來講就是地址,加個取地址符就行
ctype.h
int isdigit(int c) 檢查所傳的字符是否是十進制數(shù)字字符。
void isalpha(int c) 檢查所傳的字符是否是字母。
int islower(int c) 檢查所傳的字符是否是小寫字母。
int isupper(int c) 檢查所傳的字符是否是大寫字母。
int ispunct(int c) 檢查所傳的字符是否是標點符號字符。標點符號字符可以是非字母數(shù)字(正如 isalnum 中的一樣)的任意圖形字符(正如 isgraph 中的一樣)。
void isalnum(int c) 檢查所傳的字符是否是字母和數(shù)字。
math.h
double modf(double x, double *integer) 返回值為小數(shù)部分(小數(shù)點后的部分),并設置 integer 為整數(shù)部分。
double pow(double x, double y) 返回 x 的 y 次冪。
double sqrt(double x) 返回 x 的平方根。
double fabs(double x) 返回 x 的絕對值。
3.stdlib.h
double atof(const char *str) 把參數(shù) str 所指向的字符串轉(zhuǎn)換為一個浮點數(shù)(類型為 double 型)。
int atoi(const char *str) 把參數(shù) str 所指向的字符串轉(zhuǎn)換為一個整數(shù)(類型為 int 型)。
double strtod(const char *str, char **endptr) 把參數(shù) str 所指向的字符串轉(zhuǎn)換為一個浮點數(shù)(類型為 double 型)。如果 endptr 不為空,則指向轉(zhuǎn)換中最后一個字符后的字符的指針會存儲在 endptr 引用的位置。
int abs(int x) 返回 x 的絕對值。
char* itoa(int value,char*string,int radix);//value: 要轉(zhuǎn)換的整數(shù),string: 轉(zhuǎn)換后的字符串,radix: 轉(zhuǎn)換進制數(shù),如2,8,10,16 進制等。
4.string.h
int memcmp(const void *str1, const void *str2, size_t n)) 把存儲區(qū) str1 和存儲區(qū) str2 的前 n 個字節(jié)進行比較。
int strcmp(const char *str1, const char *str2) 把 str1 所指向的字符串和 str2 所指向的字符串進行比較。
size_t strlen(const char *str) 計算字符串 str 的長度,直到空結(jié)束字符,但不包括空結(jié)束字符。
char strcat(char *destin, char *source);連接字符串
char strrev(char *str);串倒轉(zhuǎn)
char *strupr(char *str);將串中的小寫字母轉(zhuǎn)換為大寫字母
char *strstr(char *str1, char *str2);在串中查找指定字符串的第一次出現(xiàn)
萬能算法——分而治之(D&Z)
這是本章唯一的真正的算法,也是真正萬能的一種算法
分而治之方法與軟件設計的模塊化方法非常相似。為了解決一個大的問題,可以: 1) 把它分成兩個或多個更小的問題; 2) 分別解決每個小問題; 3) 把各小問題的解答組合起來,即可得到原問題的解答。小問題通常與原問題相似,可以遞歸地使用分而治之策略來解決。
例2-1 [找出偽幣] 給你一個裝有1 6個硬幣的袋子。1 6個硬幣中有一個是偽造的,并且那個偽造的硬幣比真的硬幣要輕一些。你的任務是找出這個偽造的硬幣。為了幫助你完成這一任務,將提供一臺可用來比較兩組硬幣重量的儀器,利用這臺儀器,可以知道兩組硬幣的重量是否相同。比較硬幣1與硬幣2的重量。假如硬幣1比硬幣2輕,則硬幣1是偽造的;假如硬幣2比硬幣1輕,則硬幣2是偽造的。這樣就完成了任務。假如兩硬幣重量相等,則比較硬幣3和硬幣4。同樣,假如有一個硬幣輕一些,則尋找偽幣的任務完成。假如兩硬幣重量相等,則繼續(xù)比較硬幣5和硬幣6。按照這種方式,可以最多通過8次比較來判斷偽幣的存在并找出這一偽幣。
另外一種方法就是利用分而治之方法。假如把1 6硬幣的例子看成一個大的問題。第一步,把這一問題分成兩個小問題。隨機選擇8個硬幣作為第一組稱為A組,剩下的8個硬幣作為第二組稱為B組。這樣,就把1 6個硬幣的問題分成兩個8硬幣的問題來解決。第二步,判斷A和B組中是否有偽幣??梢岳脙x器來比較A組硬幣和B組硬幣的重量。假如兩組硬幣重量相等,則可以判斷偽幣不存在。假如兩組硬幣重量不相等,則存在偽幣,并且可以判斷它位于較輕的那一組硬幣中。最后,在第三步中,用第二步的結(jié)果得出原先1 6個硬幣問題的答案。若僅僅判斷硬幣是否存在,則第三步非常簡單。無論A組還是B組中有偽幣,都可以推斷這1 6個硬幣中存在偽幣。因此,僅僅通過一次重量的比較,就可以判斷偽幣是否存在。
現(xiàn)在假設需要識別出這一偽幣。把兩個或三個硬幣的情況作為不可再分的小問題。注意如果只有一個硬幣,那么不能判斷出它是否就是偽幣。在一個小問題中,通過將一個硬幣分別與其他兩個硬幣比較,最多比較兩次就可以找到偽幣。這樣,1 6硬幣的問題就被分為兩個8硬幣(A組和B組)的問題。通過比較這兩組硬幣的重量,可以判斷偽幣是否存在。如果沒有偽幣,則算法終止。否則,繼續(xù)劃分這兩組硬幣來尋找偽幣。假設B是輕的那一組,因此再把它分成兩組,每組有4個硬幣。稱其中一組為B1,另一組為B2。比較這兩組,肯定有一組輕一些。如果B1輕,則偽幣在B1中,再將B1又分成兩組,每組有兩個硬幣,稱其中一組為B1a,另一組為B1b。比較這兩組,可以得到一個較輕的組。由于這個組只有兩個硬幣,因此不必再細分。比較組中兩個硬幣的重量,可以立即知道哪一個硬幣輕一些。較輕的硬幣就是所要找的偽幣。
例2-2 [金塊問題] 有一個老板有一袋金塊。每個月將有兩名雇員會因其優(yōu)異的表現(xiàn)分別被獎勵一個金塊。按規(guī)矩,排名第一的雇員將得到袋中最重的金塊,排名第二的雇員將得到袋中最輕的金塊。根據(jù)這種方式,除非有新的金塊加入袋中,否則第一名雇員所得到的金塊總是比第二名雇員所得到的金塊重。如果有新的金塊周期性的加入袋中,則每個月都必須找出最輕和最重的金塊。假設有一臺比較重量的儀器,我們希望用最少的比較次數(shù)找出最輕和最重的金塊。
假設袋中有n 個金塊??梢杂煤瘮?shù)M a x(程序1 - 3 1)通過n-1次比較找到最重的金塊。找到最重的金塊后,可以從余下的n-1個金塊中用類似的方法通過n-2次比較找出最輕的金塊。這樣,比較的總次數(shù)為2n-3。程序2 - 2 6和2 - 2 7是另外兩種方法,前者需要進行2n-2次比較,后者最多需要進行2n-2次比較。
下面用分而治之方法對這個問題進行求解。當n很小時,比如說, n≤2,識別出最重和最輕的金塊,一次比較就足夠了。當n 較大時(n>2),第一步,把這袋金塊平分成兩個小袋A和B。第二步,分別找出在A和B中最重和最輕的金塊。設A中最重和最輕的金塊分別為HA 與LA,以此類推,B中最重和最輕的金塊分別為HB 和LB。第三步,通過比較HA 和HB,可以找到所有金塊中最重的;通過比較LA 和LB,可以找到所有金塊中最輕的。在第二步中,若n>2,則遞歸地應用分而治之方法。
假設n= 8。這個袋子被平分為各有4個金塊的兩個袋子A和B。為了在A中找出最重和最輕的金塊,A中的4個金塊被分成兩組A1和A2。每一組有兩個金塊,可以用一次比較在A中找出較重的金塊HA1和較輕的金塊LA1。經(jīng)過另外一次比較,又能找出HA 2和LA 2。現(xiàn)在通過比較HA1和HA2,能找出HA;通過LA 1和LA2的比較找出LA。這樣,通過4次比較可以找到HA 和LA。同樣需要另外4次比較來確定HB 和LB。通過比較HA 和HB(LA 和LB),就能找出所有金塊中最重和最輕的。因此,當n= 8時,這種分而治之的方法需要1 0次比較。如果使用程序1 - 3 1,則需要1 3次比較。如果使用程序2 - 2 6和2 - 2 7,則最多需要1 4次比較。設c(n)為使用分而治之方法所需要的比較次數(shù)。為了簡便,假設n是2的冪。當n= 2時,c(n) = 1。對于較大的n,c(n) = 2c(n/ 2 ) + 2。當n是2的冪時,使用迭代方法(見例2 - 2 0)可知
c(n) = 3n/ 2 - 2。在本例中,使用分而治之方法比逐個比較的方法少用了2 5%的比較次數(shù)。
例2-3 [矩陣乘法] 兩個n×n 階的矩陣A與B的乘積是另一個n×n 階矩陣C,C可表示為假如每一個C(i, j) 都用此公式計算,則計算C所需要的操作次數(shù)為n3 m+n2 (n- 1) a,其中m表示一次乘法,a 表示一次加法或減法。
為了得到兩個矩陣相乘的分而治之算法,需要: 1) 定義一個小問題,并指明小問題是如何進行乘法運算的; 2) 確定如何把一個大的問題劃分成較小的問題,并指明如何對這些較小的問題進行乘法運算; 3) 最后指出如何根據(jù)小問題的結(jié)果得到大問題的結(jié)果。為了使討論簡便,假設n 是2的冪(也就是說, n是1,2,4,8,1 6,.)。
首先,假設n= 1時是一個小問題,n> 1時為一個大問題。后面將根據(jù)需要隨時修改這個假設。對于1×1階的小矩陣,可以通過將兩矩陣中的兩個元素直接相乘而得到結(jié)果。
考察一個n> 1的大問題??梢詫⑦@樣的矩陣分成4個n/ 2×n/ 2階的矩陣A1,A2,A3,和A4。當n 大于1且n 是2的冪時,n/ 2也是2的冪。因此較小矩陣也滿足前面對矩陣大小的假設。矩陣Bi 和Ci 的定義與此類似.
根據(jù)上述公式,經(jīng)過8次n/ 2×n/ 2階矩陣乘法和4次n/ 2×n/ 2階矩陣的加法,就可以計算出A與B的乘積。因此,這些公式能幫助我們實現(xiàn)分而治之算法。在算法的第二步,將遞歸使用分而治之算法把8個小矩陣再細分(見程序2 - 1 9)。算法的復雜性為(n3 ),此復雜性與程序2 - 2 4直接使用公式(2 - 1)所得到的復雜性是一樣的。事實上,由于矩陣分割和再組合所花費的額外開銷,使用分而治之算法得出結(jié)果的時間將比用程序2 - 2 4還要長。
為了得到更快的算法,需要簡化矩陣分割和再組合這兩個步驟。一種方案是使用S t r a s s e n方法得到7個小矩陣。這7個小矩陣為矩陣D, E, ., J,矩陣D到J可以通過7次矩陣乘法, 6次矩陣加法,和4次矩陣減法計算得出。前述的4個小矩陣可以由矩陣D到J通過6次矩陣加法和兩次矩陣減法得出.
用上述方案來解決n= 2的矩陣乘法。將某矩陣A和B相乘得結(jié)果C,如下所示:
因為n> 1,所以將A、B兩矩陣分別劃分為4個小矩陣,每個矩陣為1×1階,僅包含一個元素。1×1階矩陣的乘法為小問題,因此可以直接進行運算。利用計算D~J的公式,得:
D= 1(6-8)=-2
E= 4(7-5)= 8
F=(3 + 4)5 = 3 5
G=(1 + 2)8 = 2 4
H=(3-1)(5 + 6)= 2 2
I=(2-4)(7 + 8)=-3 0
J=(1 + 4)(5 + 8)= 6 5
根據(jù)以上結(jié)果可得:
對于上面這個2×2的例子,使用分而治之算法需要7次乘法和1 8次加/減法運算。而直接使用公式(2 - 1),則需要8次乘法和7次加/減法。要想使分而治之算法更快一些,則一次乘法所花費的時間必須比11次加/減法的時間要長。
假定S t r a s s e n矩陣分割方案僅用于n≥8的矩陣乘法,而對于n<8的矩陣乘法則直接利用公式(2 - 1)進行計算。則n= 8時,8×8矩陣相乘需要7次4×4矩陣乘法和1 8次4×4矩陣加/減法。每次矩陣乘法需花費6 4m+ 4 8a次操作,每次矩陣加法或減法需花費1 6a次操作。因此總的操作次數(shù)為7 ( 6 4m+ 4 8a) + 1 8 ( 1 6a) = 4 4 8m+ 6 2 4a。而使用直接計算方法,則需要5 1 2m+ 4 4 8a次操作。要使S t r a s s e n方法比直接計算方法快,至少要求5 1 2-4 4 8次乘法的開銷比6 2 4-4 4 8次加/減法的開銷大?;蛘哒f一次乘法的開銷應該大于近似2 . 7 5次加/減法的開銷。
假定n<1 6的矩陣是一個"小"問題,S t r a s s e n的分解方案僅僅用于n≥1 6的情況,對于n<1 6的矩陣相乘,直接利用公式( 2 - 1)。則當n= 1 6時使用分而治之算法需要7 ( 5 1 2m+ 4 4 8a) +1 8 ( 6 4a) = 3 5 8 4m+ 4 2 8 8a次操作。直接計算時需要4 0 9 6m+ 3 8 4 0a次操作。若一次乘法的開銷與一次加/減法的開銷相同,則S t r a s s e n方法需要7 8 7 2次操作及用于問題分解的額外時間,而直接計算方法則需要7 9 3 6次操作加上程序中執(zhí)行f o r循環(huán)以及其他語句所花費的時間。即使直接計算方法所需要的操作次數(shù)比St r a s s e n方法少,但由于直接計算方法需要更多的額外開銷,因此它也不見得會比S t r a s s e n方法快。
n 的值越大,Strassen 方法與直接計算方法所用的操作次數(shù)的差異就越大,因此對于足夠大的n,Strassen 方法將更快。設t (n) 表示使用Strassen 分而治之方法所需的時間。因為大的矩陣會被遞歸地分割成小矩陣直到每個矩陣的大小小于或等于k(k至少為8,也許更大,具體值由計算機的性能決定). 用迭代方法計算,可得t(n) = (nl og27 )。因為l og27 ≈2 . 8 1,所以與直接計算方法的復雜性(n3 )相比,分而治之矩陣乘法算法有較大的改進。
面對新問題時,你不再束手無策,而是自問:“使用分而治之能解決嗎”!!!
重申下工作原理:
找出簡單的基線條件條件
確定如何縮小問題的規(guī)模,使其符合基線條件
基本程序段
最大公約數(shù)
窮舉
for(i=1; i <= n1 && i <= n2; ++i){// 判斷 i 是否為最大公約數(shù)if(n1%i==0 && n2%i==0)gcd = i;}printf("%d 和 %d 的最大公約數(shù)是 %d", n1, n2, gcd);輾轉(zhuǎn)相除
r=a%b; while(r) {a=b;b=r;r=a%b; }return b;判斷數(shù)字位數(shù)
while(n != 0){// n = n/10n /= 10;++count;}printf("數(shù)字是 %d 位數(shù)。", count);判斷回文數(shù)(逆序)
yuanshu = n;// 逆序while( n!=0 ){weishu = n%10;nixushu = nixushu*10 + weishu;n /= 10;}// 判斷if(yuanshu == nixushu)printf("%d 是回文數(shù)。", yuanshu);elseprintf("%d 不是回文數(shù)。", yuanshu);二進制轉(zhuǎn)十進制(進制轉(zhuǎn)換)
int sjz = 0, i = 0, ws;while (n!=0){ws = n%10;n /= 10;sjz += ws*pow(2,i);//十進制以內(nèi)其余進制轉(zhuǎn)十進制,將2改為進制數(shù)即可++i;}return sjz;矩陣轉(zhuǎn)置
// 轉(zhuǎn)換for(i=0; i<r; ++i)for(j=0; j<c; ++j){transpose[j][i] = a[i][j];//公式不定,請看具體題目進行分析}排序
冒泡
for (i = 0; i < len - 1; i++)for (j = 0; j < len - 1 - i; j++)if (arr[j] > arr[j + 1]) {temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}選擇
for (i = 0 ; i < len - 1 ; i++) {int min = i; // 記錄最小值,第一個元素默認最小for (j = i + 1; j < len; j++) // 訪問未排序的元素{if (a[j] < a[min]) // 找到目前最小值{min = j; // 記錄最小值}}if(min != i){temp=a[min]; // 交換兩個變量a[min]=a[i];a[i]=temp;}}插入
for (i=1;i<len;i++){temp = arr[i];for (j=i;j>0 && arr[j-1]>temp;j--)arr[j] = arr[j-1];arr[j] = temp;}順序
for(i=0;i<n-1;i++)for(j=i+1;j<n;j++)if(a[i]>a[j]){t=a[i];a[i]=a[j];a[j]=t;}移位
左移
x=a[0]; for(i=n-2;i>=0;i--)a[i+1]=a[i]; a[0]=x;右移
x=a[n-1]; for(i=n-2;i>=0;i--)a[i+1]=a[i]; a[0]=x;刪除
刪除法
for(i=0;i<n;i++){if(x==a[i]){n--;for(j=i;j<n;j++)a[j]=a[j+1];i--;}}保留法
j=0; for(i=0;i<n;i++)if(x!=a[i])b[j++]=a[i];插入
for(i=0;i<n-1;i++)if(x<a[i]){for(j=n-2;j>=i;j--)a[j+1]=a[j];a[i]=x;break;}進階程序段
字符串取數(shù)據(jù)
取數(shù)字
h=0; for(i=0;s[i];i++){if(isdigit(s[i])){sum=0;while(isdigit(s[i]))sum=sum*10+s[i++]-48;a[h++]=sum;}}未完待續(xù),敬請期待
——by 何為
總結(jié)
以上是生活随笔為你收集整理的江蘇省單招c語言技能編程詳解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CEF | CEF浏览器客户端功能详解
- 下一篇: SCRUM项目中的产品分解图和Sprin