




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、C語(yǔ)言常用算法歸納 應(yīng)當(dāng)掌握的一般算法一、基本算法:交換、累加、累乘二、非數(shù)值計(jì)算常用經(jīng)典算法:窮舉、排序(冒泡,選擇)、查找(順序即線性)三、數(shù)值計(jì)算常用經(jīng)典算法:級(jí)數(shù)計(jì)算(直接、簡(jiǎn)接即遞推)、一元非線性方程求根(牛頓迭代法、二分法)、定積分計(jì)算(矩形法、梯形法)四、其他:迭代、進(jìn)制轉(zhuǎn)換、矩陣轉(zhuǎn)置、字符處理(統(tǒng)計(jì)、數(shù)字串、字母大小寫轉(zhuǎn)換、加密等)、整數(shù)各數(shù)位上數(shù)字的獲取、輾轉(zhuǎn)相除法求最大公約數(shù)(最小公倍數(shù))、求最值、判斷素?cái)?shù)(各種變形)、數(shù)組元素的插入(刪除)、二維數(shù)組的其他典型問(wèn)題(方陣的特點(diǎn)、楊輝三角形)詳細(xì)講解一、基本算法 1交換(兩量交換借助第三者)例1、任意讀
2、入兩個(gè)整數(shù),將二者的值交換后輸出。 main() int a,b,t; scanf("%d%d",&a,&b); printf("%d,%dn",a,b);t=a; a=b; b=t; printf("%d,%dn",a,b);【解析】程序中加粗部分為算法的核心,如同交換兩個(gè)杯子里的飲料,必須借助第三個(gè)空杯子。假設(shè)輸入的值分別為3、7,則第一行輸出為3,7;第二行輸出為7,3。其中t為中間變量,起到“空杯子”
3、的作用。注意:三句賦值語(yǔ)句賦值號(hào)左右的各量之間的關(guān)系!【應(yīng)用】例2、任意讀入三個(gè)整數(shù),然后按從小到大的順序輸出。main() int a,b,c,t; scanf("%d%d%d",&a,&b,&c); /*以下兩個(gè)if語(yǔ)句使得a中存放的數(shù)最小*/ if(a>b) t=a; a=b; b=t; if(a>c) t=a; a=c; c=t; /*以下if語(yǔ)句使得b中存放的數(shù)次小*/
4、 if(b>c) t=b; b=c; c=t; printf("%d,%d,%dn",a,b,c);2累加累加算法的要領(lǐng)是形如“s=s+A”的累加式,此式必須出現(xiàn)在循環(huán)中才能被反復(fù)執(zhí)行,從而實(shí)現(xiàn)累加功能?!癆”通常是有規(guī)律變化的表達(dá)式,s在進(jìn)入循環(huán)前必須獲得合適的初值,通常為0。例1、求1+2+3+100的和。main() int i,s; s=0; i=1; while(i<=100) s=s+i;
5、0; /*累加式*/ i=i+1; /*特殊的累加式*/ printf("1+2+3+.+100=%dn",s);【解析】程序中加粗部分為累加式的典型形式,賦值號(hào)左右都出現(xiàn)的變量稱為累加器,其中“i = i + 1”為特殊的累加式,每次累加的值為1,這樣的累加器又稱為計(jì)數(shù)器。3累乘累乘算法的要領(lǐng)是形如“s=s*A
6、”的累乘式,此式必須出現(xiàn)在循環(huán)中才能被反復(fù)執(zhí)行,從而實(shí)現(xiàn)累乘功能?!癆”通常是有規(guī)律變化的表達(dá)式,s在進(jìn)入循環(huán)前必須獲得合適的初值,通常為1。例1、求10!分析 10!=1×2×3××10main() int i; long c; c=1; i=1; while(i<=10) c=c*i; /*累乘式*/ i=i+1; printf(&
7、quot;1*2*3*.*10=%ldn",c);二、非數(shù)值計(jì)算常用經(jīng)典算法1窮舉也稱為“枚舉法”,即將可能出現(xiàn)的每一種情況一一測(cè)試,判斷是否滿足條件,一般采用循環(huán)來(lái)實(shí)現(xiàn)。例1、用窮舉法輸出所有的水仙花數(shù)(即這樣的三位正整數(shù):其每位數(shù)位上的數(shù)字的立方和與該數(shù)相等,比如:1*1*1+5*5*5+3*3*3=153)。法一main() int x,g,s,b; for(x=100;x<=999;x+) g=x%10; s=x/10%10; b=x/100; i
8、f(b*b*b+s*s*s+g*g*g=x)printf("%dn",x);【解析】此方法是將100到999所有的三位正整數(shù)一一考察,即將每一個(gè)三位正整數(shù)的個(gè)位數(shù)、十位數(shù)、百位數(shù)一一求出(各數(shù)位上的數(shù)字的提取算法見(jiàn)下面的“數(shù)字處理”),算出三者的立方和,一旦與原數(shù)相等就輸出。共考慮了900個(gè)三位正整數(shù)。法二main()int g,s,b; for(b=1;b<=9;b+) for(s=0;s<=9;s+) for(g=0;g<=9;g+) &
9、#160;if(b*b*b+s*s*s+g*g*g=b*100+s*10+g) printf("%dn",b*100+s*10+g);【解析】此方法是用1到9做百位數(shù)字、0到9做十位和個(gè)位數(shù)字,將組成的三位正整數(shù)與每一組的三個(gè)數(shù)的立方和進(jìn)行比較,一旦相等就輸出。共考慮了900個(gè)組合(外循環(huán)單獨(dú)執(zhí)行的次數(shù)為9,兩個(gè)內(nèi)循環(huán)單獨(dú)執(zhí)行的次數(shù)分別為10次,故if語(yǔ)句被執(zhí)行的次數(shù)為9×10×10=900),即900個(gè)三位正整數(shù)。與法一判斷的次數(shù)一樣。2排序(1)冒泡排序(起泡排序)假設(shè)要對(duì)含有n個(gè)數(shù)的序列進(jìn)行升序排列,冒泡排序算法步驟是:從存放
10、序列的數(shù)組中的第一個(gè)元素開(kāi)始到最后一個(gè)元素,依次對(duì)相鄰兩數(shù)進(jìn)行比較,若前者大后者小,則交換兩數(shù)的位置;第趟結(jié)束后,最大數(shù)就存放到數(shù)組的最后一個(gè)元素里了,然后從第一個(gè)元素開(kāi)始到倒數(shù)第二個(gè)元素,依次對(duì)相鄰兩數(shù)進(jìn)行比較,若前者大后者小,則交換兩數(shù)的位置;重復(fù)步驟n-1趟,每趟比前一趟少比較一次,即可完成所求。例1、任意讀入10個(gè)整數(shù),將其用冒泡法按升序排列后輸出。#define n 10 main() int an,i,j,t; for(i=0;i<n;i+) scanf("%d",&ai);
11、 for(j=1;j<=n-1;j+) /*n個(gè)數(shù)處理n-1趟*/ for(i=0;i<=n-1-j;i+) /*每趟比前一趟少比較一次*/ if(ai>ai+1) t=ai;ai=ai+1;ai+1=t; for(i=0;i<n;i+) printf("%dn",ai);(2)選擇法排序選擇法排序是相對(duì)好理解的排序算法。假設(shè)要對(duì)含有n個(gè)數(shù)的序列進(jìn)行升序排列,算法步驟是:從數(shù)組存放的n個(gè)數(shù)中找出最小數(shù)的下標(biāo)(算法見(jiàn)下面
12、的“求最值”),然后將最小數(shù)與第1個(gè)數(shù)交換位置;除第1個(gè)數(shù)以外,再?gòu)钠溆鄋-1個(gè)數(shù)中找出最小數(shù)(即n個(gè)數(shù)中的次小數(shù))的下標(biāo),將此數(shù)與第2個(gè)數(shù)交換位置;重復(fù)步驟n-1趟,即可完成所求。例1、任意讀入10個(gè)整數(shù),將其用選擇法按升序排列后輸出。#define n 10 main() int an,i,j,k,t; for(i=0;i<n;i+) scanf("%d",&ai); for(i=0;i<n-1;i+)
13、60; /*處理n-1趟*/ k = i; /*總是假設(shè)此趟處理的第一個(gè)(即全部數(shù)的第i個(gè))數(shù)最小,k記錄其下標(biāo)*/ for(j=i+1;j<n;j+) if(aj < ak) k = j; if (k
14、;!= i) t = ai; ai = ak; ak = t; for(i=0;i<n;i+) printf("%dn",ai); (3)插入法排序要想很好地掌握此算法,先請(qǐng)了解“有序序列的插入算法”,就是將某數(shù)據(jù)插入到一個(gè)有序序列后,該序列仍然有序。插入算法參見(jiàn)下面的“數(shù)組元素的插入”。例1、將任意讀入的整數(shù)x插入一升序數(shù)列后,數(shù)列仍按升序排列。#define n
15、;10main() int an=-1,3,6,9,13,22,27,32,49,x,j,k; /*注意留一個(gè)空間給待插數(shù)*/ scanf("%d",&x); if(x>an-2) an-1=x /*比最后一個(gè)數(shù)還大就往最后一個(gè)元素中存放*/ else /*查找待插位置*/ j=0; while( j<=n-2
16、0;&& x>aj) j+; for(k=n-2; k>=j; k- -) /*從最后一個(gè)數(shù)開(kāi)始直到待插位置上的數(shù)依次后移一位*/ak+1=ak; aj=x; /*插入待插數(shù)*/ for(j=0;j<=n-1;j+) printf("%d ",aj);插入法排序的要領(lǐng)就是每讀入一
17、個(gè)數(shù)立即插入到最終存放的數(shù)組中,每次插入都使得該數(shù)組有序。例2、任意讀入10個(gè)整數(shù),將其用插入法按降序排列后輸出。(提示:將第2至第10個(gè)數(shù)一一有序插入到數(shù)組a中)#define n 10 main() int an,i,j,k,x; scanf("%d",&a0); /*讀入第一個(gè)數(shù),直接存到a0中*/ for(j=1;j<n;j+) /*將第2至第10個(gè)數(shù)一一有序插入到數(shù)組a中*/ scanf("%d&
18、quot;,&x); if(x<aj-1) aj=x; /*比原數(shù)列最后一個(gè)數(shù)還小就往最后一個(gè)元素之后存放新讀的數(shù)*/ else /*以下查找待插位置*/ i=0; while(x<ai&&i<=j-1) i+; /*以下for循環(huán)從
19、原最后一個(gè)數(shù)開(kāi)始直到待插位置上的數(shù)依次后移一位*/ for(k=j-1;k>=i;k-) ak+1=ak; ai=x; /*插入待插數(shù)*/ for(i=0;i<n;i+) printf("%dn",ai);(4)歸并排序
20、; 即將兩個(gè)都升序(或降序)排列的數(shù)據(jù)序列合并成一個(gè)仍按原序排列的序列。例1、有一個(gè)含有6個(gè)數(shù)據(jù)的升序序列和一個(gè)含有4個(gè)數(shù)據(jù)的升序序列,將二者合并成一個(gè)含有10個(gè)數(shù)據(jù)的升序序列。#define m 6#define n 4main() int am=-3,6,19,26,68,100 ,bn=8,10,12,22; int i,j,k,cm+n; i=j=k=0;while(i<m && j<n) /*將a、b數(shù)組中的較小
21、數(shù)依次存放到c數(shù)組中*/ if(ai<bj) ck=ai; i+; else ck=bj; j+; k+; while(i>=m && j<n) /*若a中數(shù)據(jù)全部存放完畢,將b中余下的數(shù)全部存放到c中*/ ck=bj; k+; j+; while(j>=n && i<m) /*若b中數(shù)據(jù)全部
22、存放完畢,將a中余下的數(shù)全部存放到c中*/ ck=ai; k+; i+; for(i=0;i<m+n;i+) printf("%d ",ci);3查找(1)順序查找(即線性查找)順序查找的思路是:將待查找的量與數(shù)組中的每一個(gè)元素進(jìn)行比較,若有一個(gè)元素與之相等則找到;若沒(méi)有一個(gè)元素與之相等則找不到。例1、任意讀入10個(gè)數(shù)存放到數(shù)組a中,然后讀入待查找數(shù)值,存放到x中,判斷a中有無(wú)與x等值的數(shù)。#define N 10main() int aN,i,x;&
23、#160;for(i=0;i<N;i+) scanf("%d",&ai); /*以下讀入待查找數(shù)值*/ scanf("%d",&x); for(i=0;i<N;i+) if(ai=x) break /*一旦找到就跳出循環(huán)*/ if(i<N) printf("Found!n"); else printf("Not found!n")
24、; (2)折半查找(即二分法)順序查找的效率較低,當(dāng)數(shù)據(jù)很多時(shí),用二分法查找可以提高效率。使用二分法查找的前提是數(shù)列必須有序。二分法查找的思路是:要查找的關(guān)鍵值同數(shù)組的中間一個(gè)元素比較,若相同則查找成功,結(jié)束;否則判別關(guān)鍵值落在數(shù)組的哪半部分,就在這半部分中按上述方法繼續(xù)比較,直到找到或數(shù)組中沒(méi)有這樣的元素值為止。例1、任意讀入一個(gè)整數(shù)x,在升序數(shù)組a中查找是否有與x等值的元素。#define n 10main() int an=2,4,7,9,12,25,36,50,77,90; int x,high,low,mid; /*x為關(guān)鍵值*/
25、160;scanf("%d",&x); high=n-1; low=0; mid=(high+low)/2; while(amid!=x&&low<high) if(x<amid) high=mid-1; /*修改區(qū)間上界*/ else low=mid+1; /*修改
26、區(qū)間下界*/ mid=(high+low)/2; if(x=amid) printf("Found %d,%dn",x,mid); else printf("Not foundn");三、數(shù)值計(jì)算常用經(jīng)典算法1級(jí)數(shù)計(jì)算級(jí)數(shù)計(jì)算的關(guān)鍵是“描述出通項(xiàng)”,而通項(xiàng)的描述法有兩種:一為直接法、二為間接法又稱遞推法。直接法的要領(lǐng)是:利用項(xiàng)次直接寫出通項(xiàng)式;遞推法的要領(lǐng)是:利用前一個(gè)(或多個(gè))通項(xiàng)寫出后一個(gè)通項(xiàng)??梢杂弥苯臃枋鐾?xiàng)的級(jí)數(shù)計(jì)算例子有:(1)1+2+3+4+
27、5+(2)1+1/2+1/3+1/4+1/5+等等。可以用間接法描述通項(xiàng)的級(jí)數(shù)計(jì)算例子有:(1)1+1/2+2/3+3/5+5/8+8/13+(2)1+1/2!+1/3!+1/4! +1/5!+等等。(1)直接法求通項(xiàng)例1、求1+1/2+1/3+1/4+1/5+1/100的和。main() float s; int i; s=0.0; for(i=1;i<=100;i+) s=s+1.0/i printf("1+1/2+1/3+.+1/100=%fn",s);【解析】程序
28、中加粗部分就是利用項(xiàng)次i的倒數(shù)直接描述出每一項(xiàng),并進(jìn)行累加。注意:因?yàn)閕是整數(shù),故分子必須寫成1.0的形式?。?)間接法求通項(xiàng)(即遞推法)例2、計(jì)算下列式子前20項(xiàng)的和:1+1/2+2/3+3/5+5/8+8/13+。分析此題后項(xiàng)的分子是前項(xiàng)的分母,后項(xiàng)的分母是前項(xiàng)分子分母之和。main() float s,fz,fm,t,fz1; int i; s=1; /*先將第一項(xiàng)的值賦給累加器s*/ fz=1;fm=2; t=fz/fm;
29、60; /*將待加的第二項(xiàng)存入t中*/ for(i=2;i<=20;i+) s=s+t; /*以下求下一項(xiàng)的分子分母*/ fz1=fz; /*將前項(xiàng)分子值保存到fz1中*/ fz=fm; /*后項(xiàng)分子等于前項(xiàng)分母*/ fm=fz1+fm; /*后項(xiàng)分母等于前項(xiàng)分子、分母之和*/
30、t=fz/fm; printf("1+1/2+2/3+.=%fn",s);下面舉一個(gè)通項(xiàng)的一部分用直接法描述,另一部分用遞推法描述的級(jí)數(shù)計(jì)算的例子:例3、計(jì)算級(jí)數(shù)的值,當(dāng)通項(xiàng)的絕對(duì)值小于eps時(shí)計(jì)算停止。#include <math.h>float g(float x,float eps);main() float x,eps; scanf("%f%f",&x,&eps); printf("n%f,%fn",x,g(x,ep
31、s);float g(float x,float eps) int n=1;float s,t; s=1; t=1; do t=t*x/(2*n); s=s+(n*n+1)*t; /*加波浪線的部分為直接法描述部分,t為遞推法描述部分*/ n+; while(fabs(t)>eps); return s;2一元非線
32、性方程求根(1)牛頓迭代法牛頓迭代法又稱牛頓切線法:先任意設(shè)定一個(gè)與真實(shí)的根接近的值x0作為第一次近似根,由x0求出f(x0),過(guò)(x0,f(x0)點(diǎn)做f(x)的切線,交x軸于x1,把它作為第二次近似根,再由x1求出f(x1),過(guò)(x1,f(x1)點(diǎn)做f(x)的切線,交x軸于x2,如此繼續(xù)下去,直到足夠接近(比如|x- x0|<1e-6時(shí))真正的根x*為止。而f '(x0)=f(x0)/( x1- x0) 所以 x1= x0- f(x0)/ f ' (
33、x0)例如,用牛頓迭代法求下列方程在1.5附近的根:2x3-4x2+3x-6=0。#include "math.h"main() float x,x0,f,f1; x=1.5; do x0=x; f=2*x0*x0*x0-4*x0*x0+3*x0-6; f1=6*x0*x0-8*x0+3; x=x0-f/f1; while(fabs(x-x0)>=1e-5);
34、160; printf ("%fn",x); (2)二分法算法要領(lǐng)是:先指定一個(gè)區(qū)間x1, x2,如果函數(shù)f(x)在此區(qū)間是單調(diào)變化的,則可以根據(jù)f(x1)和 f(x2)是否同號(hào)來(lái)確定方程f(x)=0在區(qū)間x1, x2內(nèi)是否有一個(gè)實(shí)根;如果f(x1)和 f(x2)同號(hào),則f(x) 在區(qū)間x1, x2內(nèi)無(wú)實(shí)根,要重新改變x1和x2的值。當(dāng)確定f(x) 在區(qū)間x1, x2內(nèi)有一個(gè)實(shí)根后,可采取二分法將x1, x2一分為二,再判斷在哪一個(gè)小區(qū)間中有實(shí)根。如此不斷進(jìn)行下去,
35、直到小區(qū)間足夠小為止。具體算法如下:(1)輸入x1和x2的值。(2)求f(x1)和f(x2)。(3)如果f(x1)和f(x2)同號(hào)說(shuō)明在x1, x2 內(nèi)無(wú)實(shí)根,返回步驟(1),重新輸入x1和x2的值;若f(x1)和f(x2)不同號(hào),則在區(qū)間x1, x2內(nèi)必有一個(gè)實(shí)根,執(zhí)行步驟(4)。(4)求x1和x2的中點(diǎn):x0=(x1+ x2)/2。(5)求f(x0)。(6)判斷f(x0)與f(x1)是否同號(hào)。如果同號(hào),則應(yīng)在x0, x2中尋找根,此時(shí)x1已不起作用,用x0代替x1,用f(x0)代替f(x1)。如果不同號(hào),則應(yīng)在x1, x0中尋找根
36、,此時(shí)x2已不起作用,用x0代替x2,用f(x0)代替f(x2)。(7)判斷f(x0)的絕對(duì)值是否小于某一指定的值(例如10-5)。若不小于10-5,則返回步驟(4)重復(fù)執(zhí)行步驟(4)、(5)、(6);否則執(zhí)行步驟(8)。(8)輸出x0的值,它就是所求出的近似根。例如,用二分法求方程2x3-4x2+3x-6=0在(-10,10)之間的根。#include "math.h"main() float x1,x2,x0,fx1,fx2,fx0; do printf("Enter x1&x2&quo
37、t;); scanf("%f%f",&x1,&x2); fx1=2*x1*x1*x1-4*x1*x1+3*x1-6; fx2=2*x2*x2*x2-4*x2*x2+3*x2-6; while(fx1*fx2>0);do x0=(x1+x2)/2;
38、 fx0=2*x0*x0*x0-4*x0*x0+3*x0-6; if(fx0*fx1)<0) x2=x0; fx2=fx0; else x1=x0; fx1=fx0; while(fabs(fx0)>1e-5); printf("%fn",x0);3梯形法計(jì)算定
39、積分定積分 的幾何意義是求曲線y=f(x)、x=a、x=b以及x軸所圍成的面積??梢越频匕衙娣e視為若干小的梯形面積之和。例如,把區(qū)間a, b分成n個(gè)長(zhǎng)度相等的小區(qū)間,每個(gè)小區(qū)間的長(zhǎng)度為h=(b-a)/n,第i個(gè)小梯形的面積為f(a+(i-1)·h)+f(a+i·h)·h/2,將n個(gè)小梯形面積加起來(lái)就得到定積分的近似值:根據(jù)以上分析,給出“梯形法”求定積分的N-S結(jié)構(gòu)圖:輸入?yún)^(qū)間端點(diǎn):a,b輸入等分?jǐn)?shù)nh=(b-a)/2, s=0i從1到nsi=(f(a+(i-1)*h)+f(a+i*h)*h/2s=s+si輸出s上述程
40、序的幾何意義比較明顯,容易理解。但是其中存在重復(fù)計(jì)算,每次循環(huán)都要計(jì)算小梯形的上、下底。其實(shí),前一個(gè)小梯形的下底就是后一個(gè)小梯形的上底,完全不必重復(fù)計(jì)算。為此做出如下改進(jìn):矩形法求定積分則更簡(jiǎn)單,就是將等分出來(lái)的圖形當(dāng)作矩形,而不是梯形。例如:求定積分 的值。等分?jǐn)?shù)n=1000。#include "math.h"float DJF(float a,float b) float t,h; int n,i; float HSZ(float x); n=100
41、0; h=fabs(a-b)/n; t=(HSZ(a)+HSZ(b)/2; for(i=1;i<=n-1;i+) t=t+HSZ(a+i*h); t=t*h; return(t);float HSZ(float x) return(x*x+3*x+2); main() float y; y=DJF(0,4);printf("%fn",y);四、其他常見(jiàn)算法1迭代法其基本思想是把一個(gè)復(fù)雜的計(jì)算過(guò)程轉(zhuǎn)化為簡(jiǎn)單過(guò)程的多次重復(fù)。每次重復(fù)都從
42、舊值的基礎(chǔ)上遞推出新值,并由新值代替舊值。例如,猴子吃桃問(wèn)題。猴子第一天摘下若干個(gè)桃子,當(dāng)即吃了一半,還不過(guò)癮,又多吃了一個(gè)。第二天早上又將剩下的桃子吃掉一半,又多吃了一個(gè)。以后每天早上都吃了前一天剩下的一半零一個(gè)。到第10天早上想再吃時(shí),就只剩一個(gè)桃子了。編程求第一天共摘多少桃子。main() int day,peach; peach=1; for(day=9;day>=1;day-) peach=(peach+1)*2; printf("The first day:%dn",peac
43、h);又如,用迭代法求x= 的根。求平方根的迭代公式是:xn+1=0.5×(xn+a/ xn )算法(1)設(shè)定一個(gè)初值x0。(2)用上述公式求出下一個(gè)值x1。(3)再將x1代入上述公式,求出下一個(gè)值x2。(4)如此繼續(xù)下去,直到前后兩次求出的x值(xn+1和xn)滿足以下關(guān)系:| xn+1- xn|<10-5#include "math.h"main() float a,x0,x1; scanf("%f",&a); x0=a/2;
44、60;x1=(x0+a/x0)/2; do x0=x1; x1=(x0+a/x0)/2; while(fabs(x0-x1)>=1e-5); printf("%fn",x1);2進(jìn)制轉(zhuǎn)換(1)十進(jìn)制數(shù)轉(zhuǎn)換為其他進(jìn)制數(shù)一個(gè)十進(jìn)制正整數(shù)m轉(zhuǎn)換成r進(jìn)制數(shù)的思路是,將m不斷除以r取余數(shù),直到商為0時(shí)止,以反序輸出余數(shù)序列即得到結(jié)果。注意,轉(zhuǎn)換得到的不是數(shù)值,而是數(shù)字字符串或數(shù)字串。例如,任意讀入一個(gè)十進(jìn)制正整數(shù),將其轉(zhuǎn)換成二至十六任意進(jìn)制的字符串。void t
45、ran(int m,int r,char str,int *n) char sb="0123456789ABCDEF" int i=0,g; do g=m%r; stri=sbg; m=m/r; i+; while(m!=0); *n=i;main() int x,r0; &
46、#160; /*r0為進(jìn)制基數(shù)*/ int i,n; /*n中存放生成序列的元素個(gè)數(shù)*/ char a50; scanf("%d%d",&x,&r0); if(x>0&&r0>=2&&r0<=16) tran(x,r0,a,&n);for(i=n-1;i>=0;i-) printf("%c",ai);
47、 printf("n"); else exit(0);(2)其他進(jìn)制數(shù)轉(zhuǎn)換為十進(jìn)制數(shù)其他進(jìn)制整數(shù)轉(zhuǎn)換為十進(jìn)制整數(shù)的要領(lǐng)是:“按權(quán)展開(kāi)”,例如,有二進(jìn)制數(shù)101011,則其十進(jìn)制形式為1×25+0×24+1×23+0×22+1×21+1×20=43。若r進(jìn)制數(shù)ana2a1(n位數(shù))轉(zhuǎn)換成十進(jìn)制數(shù),方法是an×r n-1+a2×r1+a1×r0。注意:其他進(jìn)制數(shù)只能以字符串形式輸入。例1、任意讀入一個(gè)
48、二至十六進(jìn)制數(shù)(字符串),轉(zhuǎn)換成十進(jìn)制數(shù)后輸出。#include "string.h"#include "ctype.h"main() char x20; int r,d; gets(x); /*輸入一個(gè)r進(jìn)制整數(shù)序列*/ scanf("%d",&r); /*輸入待處理的進(jìn)制基數(shù)2-16*/ d=Tran(x
49、,r); printf("%s=%dn",x,d);int Tran(char *p,int r) int d,i,cr; char fh,c; d=0; fh=*p; if(fh='-') p+; for(i=0;i<strlen(p);i+) c=*(p+i); if(toupper(c)>='A') cr=tou
50、pper(c)-'A'+10; else cr=c-'0' d=d*r+cr; if(fh='-') d=-d; return(d); 3矩陣轉(zhuǎn)置矩陣轉(zhuǎn)置的算法要領(lǐng)是:將一個(gè)m行n列矩陣(即m×n矩陣)的每一行轉(zhuǎn)置成另一個(gè)n×m矩陣的相應(yīng)列。例1、將以下2×3矩陣轉(zhuǎn)置后輸出。即將
51、 1 2 3 轉(zhuǎn)置成 1 4 4 5 6
52、 2 5 3&
53、#160; 6main() int a23,b32,i,j,k=1; for(i=0;i<2;i+) for(j=0;j<3;j+) aij=k+; /*以下將a的每一行轉(zhuǎn)存到b的每一列*/ for(i=0;i<2;i+) for(j=0;j<3;j+) bji=aij; for(i=0;i<3;i+)
54、160; /*輸出矩陣b*/ for(j=0;j<2;j+) printf("%3d",bij); printf("n"); 4字符處理(1)字符統(tǒng)計(jì):對(duì)字符串中各種字符出現(xiàn)的次數(shù)的統(tǒng)計(jì)。典型例題:任意讀入一個(gè)只含小寫字母的字符串,統(tǒng)計(jì)其中每個(gè)字母的個(gè)數(shù)。#include "stdio.h &quo
55、t;main() char a100; int n26=0; int i; /*定義26個(gè)計(jì)數(shù)器并置初值0*/ gets(a); for(i=0;ai!= '0' i+) /*n0中存放a的個(gè)數(shù),n1 中存放b的個(gè)數(shù)*/ nai-'a' +; /*各字符的ASCII碼值減a的ASCII碼值,正好得對(duì)應(yīng)計(jì)數(shù)器下標(biāo)*/
56、 for(i=0;i<26;i+) if(ni!=0) printf("%c :%dn ", i+'a', ni);(2)字符加密例如、對(duì)任意一個(gè)只含有英文字母的字符串,將每一個(gè)字母用其后的第三個(gè)字母替代后輸出(字母X后的第三個(gè)字母為A,字母Y后的第三個(gè)字母為B,字母Z后的第三個(gè)字母為C。) #include "stdio.h"#include "string.h"main(
57、) char a80= "China" int i; for(i=0; i<strlen(a); i+) if(ai>='x'&&ai<='z'|ai>='X'&&ai<='Z') ai= ai-26+3; &
58、#160; else ai= ai+3;puts(a); 5整數(shù)各數(shù)位上數(shù)字的獲取算法核心是利用“任何正整數(shù)整除10的余數(shù)即得該數(shù)個(gè)位上的數(shù)字”的特點(diǎn),用循環(huán)從低位到高位依次取出整數(shù)的每一數(shù)位上的數(shù)字。例1、任意讀入一個(gè)5位整數(shù),輸出其符號(hào)位及從高位到低位上的數(shù)字。main() long x; int w,q,b,s,g; scanf("%ld",&x); if(x<0) printf
59、("-,"); x=-x; w=x/10000; /*求萬(wàn)位上的數(shù)字*/ q=x/1000%10; /*求千位上的數(shù)字*/ b=x/100%10; /*求百位上的數(shù)字*/ s=x/10%10; /*求十位上的數(shù)字*/ g=x%10;
60、160; /*求個(gè)位上的數(shù)字*/ printf("%d,%d,%d,%d,%dn",w,q,b,s,g); 例2、任意讀入一個(gè)整數(shù),依次輸出其符號(hào)位及從低位到高位上的數(shù)字。分析此題讀入的整數(shù)不知道是幾位數(shù),但可以用以下示例的方法完成此題:例如讀入的整數(shù)為3796,存放在x中,執(zhí)行x%10后得余數(shù)為6并輸出;將x/10得379后賦值給x。再執(zhí)行x%10后得余數(shù)為9并輸出;將x/10得37后賦值給x直到商x為0時(shí)終止。main() long x; scan
61、f("%ld",&x); if(x<0) printf("- "); x=-x; do /*為了能正確處理0,要用do_while循環(huán)*/ printf("%d ", x%10); x=x/10
62、; while(x!=0); printf("n");例3、任意讀入一個(gè)整數(shù),依次輸出其符號(hào)位及從高位到低位上的數(shù)字。分析此題必須借助數(shù)組將依次求得的低位到高位的數(shù)字保存后,再逆序輸出。main() long x; int a20,i,j; scanf("%ld",&x); if(x<0) printf("- "); x=-x; i=0; do ai=x%
63、10; x=x/10; i+; while(x!=0); for(j=i-1;j>=0;j-) printf("%d ",aj); printf("n");6輾轉(zhuǎn)相除法求兩個(gè)正整數(shù)的最大公約數(shù)該算法的要領(lǐng)是:假設(shè)兩個(gè)正整數(shù)為a和b,先求出前者除以后者的余數(shù),存放到變量r中,若r不為0,則將b的值得賦給a,將r的值得賦給b;再求出a除以b的余數(shù),仍然存放
64、到變量r中如此反復(fù),直至r為0時(shí)終止,此時(shí)b中存放的即為原來(lái)兩數(shù)的最大公約數(shù)。例1、任意讀入兩個(gè)正整數(shù),求出它們的最大公約數(shù)。 法一:用while循環(huán)時(shí),最大公約數(shù)存放于b中main() int a,b,r; do scanf("%d%d",&a,&b); while(a<=0|b<=0); /*確保a和b為正整數(shù)*/ r=a%b; while(r!=0) a=b;b=r;r=a%b; printf("%d
65、n",b); 法二:用dowhile循環(huán)時(shí),最大公約數(shù)存放于a中main() int a,b,r; do scanf("%d%d",&a,&b); while(a<=0|b<=0); /*確保a和b為正整數(shù)*/ do r=a%b;a=b;b=r; while(r!=0); printf("%dn",a);【引申】可以利用最大公約數(shù)求最小公倍數(shù)。提示:兩個(gè)正整數(shù)a和b的最小公倍數(shù)=
66、a×b/最大公約數(shù)。例2、任意讀入兩個(gè)正整數(shù),求出它們的最小公倍數(shù)。法一:利用最大公約數(shù)求最小公倍數(shù)main() int a,b,r,x,y; do scanf("%d%d",&a,&b); while(a<=0|b<=0); /*確保a和b為正整數(shù)*/ x=a; y=b; /*保留a、b原來(lái)的值*/
67、;r=a%b; while(r!=0) a=b;b=r;r=a%b; printf("%dn",x*y/b); 法二:若其中一數(shù)的最小倍數(shù)也是另一數(shù)的倍數(shù),該最小倍數(shù)即為所求main() int a,b,r,i; do scanf("%d%d",&a,&b); while(a<=0|b<=0); /*確保a和b為正整數(shù)*/ i=1; while(a*i%b!=0)
68、i+; printf("%dn",i*a);7求最值 即求若干數(shù)據(jù)中的最大值(或最小值)。算法要領(lǐng)是:首先將若干數(shù)據(jù)存放于數(shù)組中,通常假設(shè)第一個(gè)元素即為最大值(或最小值),賦值給最終存放最大值(或最小值)的max(或min)變量中,然后將該量max(或min)的值與數(shù)組其余每一個(gè)元素進(jìn)行比較,一旦比該量還大(或?。?,則將此元素的值賦給max(或min)所有數(shù)如此比較完畢,即可求得最大值(或最小值)。例1、任意讀入10個(gè)數(shù),輸出其中的最大值與最小值。#define N 10main() int
69、0;aN,i,max,min; for(i=0;i<N;i+) scanf("%d",&ai); max=min=a0; for(i=1;i<N;i+) if(ai>max) max=ai; else if(ai<min) min=ai; printf("max=%d,min=%dn",max,min);8判斷素?cái)?shù)素?cái)?shù)又稱質(zhì)數(shù),即“只能被1和自身整除的大于1的自然數(shù)”。判
70、斷素?cái)?shù)的算法要領(lǐng)就是依據(jù)數(shù)學(xué)定義,即若該大于1的正整數(shù)不能被2至自身減1整除,就是素?cái)?shù)。例1、任意讀入一個(gè)正整數(shù),判斷其是否為素?cái)?shù)。main() int x,k; do scanf("%d",&x); while(x<=1); /*確保讀入大于1的正整數(shù)*/ for(k=2;k<=x-1;k+) if(x%k=0) break; /*一旦能被2自身-1整除,就不可能是素?cái)?shù)*/
71、if(k=x) printf("%d is sushun",x); else printf("%d is not sushun",x);以上例題可以用以下兩種變形來(lái)解決(需要使用輔助判斷的邏輯變量):【變形一】將“2自身-1”的范圍縮小至“2自身的一半”main() int x,k,flag; do scanf("%d",&x); while(x<=1)
72、; flag=1; /*先假設(shè)x就是素?cái)?shù)*/ for(k=2;k<=x/2;k+) if(x%k=0) flag=0; break; /*一旦不可能是素?cái)?shù),即置flag為0*/ if(flag=1) printf("%d is sushun",x); else printf("%d is not sushun",x); 【變形二】將“
73、2自身-1”的范圍縮小至“2自身的平方根”#include "math.h"main() int x,k,flag; do scanf("%d",&x); while(x<=1); flag=1; /*先假設(shè)x就是素?cái)?shù)*/ for(k=2;k<=(int)sqrt(x);k+) if(x%k=0) flag=0; break; /*一旦不可能是素?cái)?shù),即
74、置flag為0*/ if(flag=1) printf("%d is sushun",x); else printf("%d is not sushun",x); 例2、用篩選法求得100以內(nèi)的所有素?cái)?shù)。算法為:(1)定義一維數(shù)組a,其初值為:2,3,100; (2)若ak不為0,則將該元素以后的所有ak的倍數(shù)的數(shù)組元素置為0;(3)a中不為0的元
75、素,均為素?cái)?shù)。 #include <math.
76、h> #include <stdio.h> main( ) int k,j,a101; clrscr(); /*清屏函數(shù)*/ for(k=2;k<101;k+) ak=k; for
77、(k=2;k<sqrt(101);k+) for(j=k+1;j<101;j+) if(ak!=0&&aj!=0) if(aj%ak=0)aj=0; for(k=2;k<101;k+)
78、;if(ak!=0)printf("%5d",ak);9數(shù)組元素的插入、刪除(1)數(shù)組元素的插入此算法一般是在已經(jīng)有序的數(shù)組中再插入一個(gè)數(shù)據(jù),使數(shù)組中的數(shù)列依然有序。算法要領(lǐng)是:假設(shè)待插數(shù)據(jù)為x,數(shù)組a中數(shù)據(jù)為升序序列。先將x與a數(shù)組當(dāng)前最后一個(gè)元素進(jìn)行比較,若比最后一個(gè)元素還大,就將x放入其后一個(gè)元素中;否則進(jìn)行以下步驟;先查找到待插位置。從數(shù)組a的第1個(gè)元素開(kāi)始找到不比x小的第一個(gè)元素,設(shè)其下標(biāo)為i ;將數(shù)組a中原最后一個(gè)元素至第i個(gè)元素依次一一后移一位,讓出待插數(shù)據(jù)的位置,即下標(biāo)為i的位置;將x存放到a(i)中。例題參見(jiàn)前面“排序中插入法排序的例1”。(2)
79、數(shù)組元素的刪除此算法的要領(lǐng)是:首先要找到(也可能找不到)待刪除元素在數(shù)組中的位置(即下標(biāo)),然后將待刪元素后的每一個(gè)元素向前移動(dòng)一位,最后將數(shù)組元素的個(gè)數(shù)減1。例1、數(shù)組a中有若干不同考試分?jǐn)?shù),任意讀入一個(gè)分?jǐn)?shù),若與數(shù)組a中某一元素值相等,就將該元素刪除。#define N 6main() int fsN=69,90,85,56,44,80,x; int i,j,n; n=N; scanf("%d",&x); /*任意讀入一個(gè)分?jǐn)?shù)值*/ /*以下查找待刪
80、分?jǐn)?shù)的位置,即元素下標(biāo)*/ for(i=0;i<n;i+) if(fsi=x) break; if(i=n) printf("Not found!n"); else /*將待刪位置之后的所有元素一一前移*/ for(j=i+1;j<n;j+) fsj-1=fsj; n=n-1;
81、160;/*元素個(gè)數(shù)減1*/ for(i=0;i<n;i+) printf("%d ",fsi);10二維數(shù)組的其他典型問(wèn)題(1)方陣的特點(diǎn)行列相等的矩陣又稱方陣。其兩條對(duì)角線中“”方向的為主對(duì)角線,“/”方向的為副對(duì)角線。主對(duì)角線上各元素的下標(biāo)特點(diǎn)為:行列值相等;副對(duì)角線上各元素的下標(biāo)特點(diǎn)為:行列值之和都為階數(shù)加1。主對(duì)角線及其以下部分(行值大于列值)稱為下三角。例1、輸出如下5階方陣。 1 2 &
82、#160; 2 2 2 3 1 2 2 2 3 3 1 2 2 3
83、; 3 3 1 2 3 3 3 3 1#define N 5main() int aNN,i,j; for(i=0;i<N;i+) for(j=0;j<N;j+)
84、0; if(i=j) aij=1; else if(i<j) aij=2; else aij=3; for(i=0;i<N;i+) for(j=0;j<N;j+) printf("%3d",aij); printf("n"); &
85、#160;例2、輸出如下5階方陣。 1 2 3 4 5 2 3 4 5 6 3 4 5 6 7 4
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年安徽國(guó)防科技職業(yè)學(xué)院?jiǎn)握新殬I(yè)傾向性考試題庫(kù)及答案一套
- 2025年短視頻廣告代理合同
- 2025年北京市實(shí)習(xí)生勞動(dòng)合同范文
- 2025年體育賽事委托合同規(guī)定
- 2025年企業(yè)資產(chǎn)租賃合同模板
- 2025年產(chǎn)品保養(yǎng)合同
- 2025年公共停車設(shè)施合同
- 2025年個(gè)人建房合同協(xié)議書樣本
- 2025年企業(yè)食堂烹飪?nèi)藛T勞動(dòng)合同
- 2025年氫氧化鈣銷售代理合同
- 2023年全國(guó)高考體育單招考試英語(yǔ)試卷試題真題(精校打印版)
- 2023年四川省綿陽(yáng)市中考化學(xué)試卷真題(含答案與解析)
- 財(cái)務(wù)管理中的財(cái)務(wù)指標(biāo)
- 2016-2023年青島酒店管理職業(yè)技術(shù)學(xué)院高職單招(英語(yǔ)/數(shù)學(xué)/語(yǔ)文)筆試歷年參考題庫(kù)含答案解析
- 第二章-環(huán)境數(shù)據(jù)統(tǒng)計(jì)與分析
- 電力各種材料重量表總
- 腸道健康講座活動(dòng)策劃
- 醫(yī)療器械(耗材)項(xiàng)目投標(biāo)服務(wù)投標(biāo)方案(技術(shù)方案)
- 小學(xué)三年級(jí)下冊(cè)數(shù)學(xué)教案3篇
- pci術(shù)后術(shù)肢腫脹處理流程
- 遼寧省營(yíng)口市2023-2024學(xué)年七年級(jí)上學(xué)期期末英語(yǔ)試題
評(píng)論
0/150
提交評(píng)論