版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
單片機(jī)常用的14個(gè)C語言算法簡(jiǎn)析算法(Algorithm):計(jì)算機(jī)解題的基本思想方法和步驟。算法的描述:是對(duì)要解決一個(gè)問題或要完成一項(xiàng)任務(wù)所采取的方法和步驟的描述,包括需要什么數(shù)據(jù)(輸入什么數(shù)據(jù)、輸出什么結(jié)果)、采用什么結(jié)構(gòu)、使用什么語句以及如何安排這些語句等。通常使用自然語言、結(jié)構(gòu)化流程圖、偽代碼等來描述算法。一、計(jì)數(shù)、求和、求階乘等簡(jiǎn)單算法此類問題都要使用循環(huán),要注意根據(jù)問題確定循環(huán)變量的初值、終值或結(jié)束條件,更要注意用來表示計(jì)數(shù)、和、階乘的變量的初值。例:用隨機(jī)函數(shù)產(chǎn)生100個(gè)[0,99]范圍內(nèi)的隨機(jī)整數(shù),統(tǒng)計(jì)個(gè)位上的數(shù)字分別為1,2,3,4,5,6,7,8,9,0的數(shù)的個(gè)數(shù)并打印出來。本題使用數(shù)組來處理,用數(shù)組a[100]存放產(chǎn)生的確100個(gè)隨機(jī)整數(shù),數(shù)組x[10]來存放個(gè)位上的數(shù)字分別為1,2,3,4,5,6,7,8,9,0的數(shù)的個(gè)數(shù)。即個(gè)位是1的個(gè)數(shù)存放在x[1]中,個(gè)位是2的個(gè)數(shù)存放在x[2]中,……個(gè)位是0的個(gè)數(shù)存放在x[10]。
voidmain(){inta[101],x[11],i,p;for(i=0;i<=11;i++)x=0;for(i=1;i<=100;i++){a=rand()%100;printf("%4d",a);if(i%10==0)printf("");}for(i=1;i<=100;i++){p="a"%10;if(p==0)p="10";x[p]=x[p]+1;}for(i=1;i<=10;i++){p="i";if(i==10)p="0";printf("%d,%d",p,x);}printf("");}二、求兩個(gè)整數(shù)的最大公約數(shù)、最小公倍數(shù)分析:求最大公約數(shù)的算法思想:(最小公倍數(shù)=兩個(gè)整數(shù)之積/最大公約數(shù))(1)對(duì)于已知兩數(shù)m,n,使得m>n;(2)m除以n得余數(shù)r;(3)若r=0,則n為求得的最大公約數(shù),算法結(jié)束;否則執(zhí)行(4);(4)m←n,n←r,再重復(fù)執(zhí)行(2)。
例如:求m="14",n=6的最大公約數(shù).
mnr1462620
voidmain(){intnm,r,n,m,t;printf("pleaseinputtwonumbers:");scanf("%d,%d",&m,&n);nm=n*m;if(m{t="n";n="m";m="t";}r=m%n;while(r!=0){m="n";n="r";r="m"%n;}printf("最大公約數(shù):%d",n);printf("最小公倍數(shù):%d",nm/n);}三、判斷素?cái)?shù)只能被1或本身整除的數(shù)稱為素?cái)?shù)基本思想:把m作為被除數(shù),將2—INT()作為除數(shù),如果都除不盡,m就是素?cái)?shù),否則就不是。(可用以下程序段實(shí)現(xiàn))voidmain(){intm,i,k;printf("pleaseinputanumber:");scanf("%d",&m);k=sqrt(m);for(i=2;iif(m%i==0)break;if(i>=k)printf("該數(shù)是素?cái)?shù)");elseprintf("該數(shù)不是素?cái)?shù)");}將其寫成一函數(shù),若為素?cái)?shù)返回1,不是則返回0intprime(m%){inti,k;k=sqrt(m);for(i=2;iif(m%i==0)return0;return1;}四、驗(yàn)證哥德巴赫猜想(任意一個(gè)大于等于6的偶數(shù)都可以分解為兩個(gè)素?cái)?shù)之和)基本思想:n為大于等于6的任一偶數(shù),可分解為n1和n2兩個(gè)數(shù),分別檢查n1和n2是否為素?cái)?shù),如都是,則為一組解。如n1不是素?cái)?shù),就不必再檢查n2是否素?cái)?shù)。先從n1=3開始,檢驗(yàn)n1和n2(n2=N-n1)是否素?cái)?shù)。然后使n1+2再檢驗(yàn)n1、n2是否素?cái)?shù),…直到n1=n/2為止。
利用上面的prime函數(shù),驗(yàn)證哥德巴赫猜想的程序代碼如下:#include"math.h"intprime(intm){inti,k;k=sqrt(m);for(i=2;iif(m%i==0)break;if(i>=k)return1;elsereturn0;}main(){intx,i;printf("pleaseinputaevennumber(>=6):");scanf("%d",&x);if(x<6||x%2!=0)printf("dataerror!");elsefor(i=2;i<=x/2;i++)if(prime(i)&′(x-i)){printf("%d+%d",i,x-i);printf("驗(yàn)證成功!");break;}}五、排序問題1.選擇法排序(升序)
基本思想:
1)對(duì)有n個(gè)數(shù)的序列(存放在數(shù)組a(n)中),從中選出最小的數(shù),與第1個(gè)數(shù)交換位置;2)除第1個(gè)數(shù)外,其余n-1個(gè)數(shù)中選最小的數(shù),與第2個(gè)數(shù)交換位置;3)依次類推,選擇了n-1次后,這個(gè)數(shù)列已按升序排列。
程序代碼如下:voidmain(){inti,j,imin,s,a[10];printf("input10numbers:");for(i=0;i<10;i++)scanf("%d",&a);for(i=0;i<9;i++){imin="i";for(j=i+1;j<10;j++)if(a[imin]>a[j])imin="j";if(i!=imin){s=a;a=a[imin];a[imin]=s;}printf("%d",a);}}2.冒泡法排序(升序)
基本思想:(將相鄰兩個(gè)數(shù)比較,小的調(diào)到前頭)
1)有n個(gè)數(shù)(存放在數(shù)組a(n)中),第一趟將每相鄰兩個(gè)數(shù)比較,小的調(diào)到前頭,經(jīng)n-1次兩兩相鄰比較后,最大的數(shù)已“沉底”,放在最后一個(gè)位置,小數(shù)上升“浮起”;2)第二趟對(duì)余下的n-1個(gè)數(shù)(最大的數(shù)已“沉底”)按上法比較,經(jīng)n-2次兩兩相鄰比較后得次大的數(shù);3)依次類推,n個(gè)數(shù)共進(jìn)行n-1趟比較,在第j趟中要進(jìn)行n-j次兩兩比較。
程序段如下voidmain(){inta[10];inti,j,t;printf("input10numbers");for(i=0;i<10;i++)scanf("%d",&a);printf("");for(j=0;j<=8;j++)for(i=0;i<9-j;i++)if(a>a[i+1]){t=a;a=a[i+1];a[i+1]=t;}printf("thesortednumbers:");for(i=0;i<10;i++)printf("%d",a);}3.合并法排序(將兩個(gè)有序數(shù)組A、B合并成另一個(gè)有序的數(shù)組C,升序)
基本思想:
1)先在A、B數(shù)組中各取第一個(gè)元素進(jìn)行比較,將小的元素放入C數(shù)組;2)取小的元素所在數(shù)組的下一個(gè)元素與另一數(shù)組中上次比較后較大的元素比較,重復(fù)上述比較過程,直到某個(gè)數(shù)組被先排完;3)將另一個(gè)數(shù)組剩余元素抄入C數(shù)組,合并排序完成。程序段如下:voidmain(){inta[10],b[10],c[20],i,ia,ib,ic;printf("pleaseinputthefirstarray:");for(i=0;i<10;i++)scanf("%d",&a);for(i=0;i<10;i++)scanf("%d",&b);printf("");ia=0;ib=0;ic=0;while(ia<10&&ib<10){if(a[ia]{c[ic]=a[ia];ia++;}else{c[ic]=b[ib];ib++;}ic++;}while(ia<=9){c[ic]=a[ia];ia++;ic++;}while(ib<=9){c[ic]=b[ib];b++;ic++;}for(i=0;i<20;i++)printf("%d",c);}六、查找問題
①順序查找法(在一列數(shù)中查找某數(shù)x)
基本思想:一列數(shù)放在數(shù)組a[1]---a[n]中,待查找的數(shù)放在x中,把x與a數(shù)組中的元素從頭到尾一一進(jìn)行比較查找。用變量p表示a數(shù)組元素下標(biāo),p初值為1,使x與a[p]比較,如果x不等于a[p],則使p=p+1,不斷重復(fù)這個(gè)過程;一旦x等于a[p]則退出循環(huán);另外,如果p大于數(shù)組長(zhǎng)度,循環(huán)也應(yīng)該停止。(這個(gè)過程可由下語句實(shí)現(xiàn))voidmain(){inta[10],p,x,i;printf("pleaseinputthearray:");for(i=0;i<10;i++)scanf("%d",&a);printf("pleaseinputthenumberyouwantfind:");scanf("%d",&x);printf("");p=0;while(x!=a[p]&&p<10)p++;if(p>=10)printf("thenumberisnotfound!");elseprintf("thenumberisfoundtheno%d!",p);}思考:將上面程序改寫一查找函數(shù)Find,若找到則返回下標(biāo)值,找不到返回-1②基本思想:一列數(shù)放在數(shù)組a[1]---a[n]中,待查找的關(guān)鍵值為key,把key與a數(shù)組中的元素從頭到尾一一進(jìn)行比較查找,若相同,查找成功,若找不到,則查找失敗。(查找子過程如下。index:存放找到元素的下標(biāo)。)voidmain(){inta[10],index,x,i;printf("pleaseinputthearray:");for(i=0;i<10;i++)scanf("%d",&a);printf("pleaseinputthenumberyouwantfind:");scanf("%d",&x);printf("");index=-1;for(i=0;i<10;i++)if(x==a){index="i";break;}if(index==-1)printf("thenumberisnotfound!");elseprintf("thenumberisfoundtheno%d!",index);}七、二分法
在一個(gè)數(shù)組中,知道一個(gè)數(shù)值,想確定他在數(shù)組中的位置下標(biāo),如數(shù)組:A[5]={1,2,6,7,9};我知道其中的值為6,那么他的下標(biāo)位置就是3。intDichotomy(int*ucData,intlong,intnum){intiDataLow=0;intiDataHigh=num-1;intiDataMIDDLE;while(iDataLow<=iDataHigh){iDataMIDDLE=(iDataHigh+iDataLow)/2;if(ucData[iDataMIDDLE]>long){iDataHigh=iDataMIDDLE-1;}elseif(ucData[iDataMIDDLE]<long){iDataLow=iDataMIDDLE+1;}else{returniDataMIDDLE;}}}八、限幅濾波法
對(duì)于隨機(jī)干擾,限幅濾波是一種有效的方法;
基本方法:比較相鄰n和n-1時(shí)刻的兩個(gè)采樣值y(n)和y(n–1),根據(jù)經(jīng)驗(yàn)確定兩次采樣允許的最大偏差。如果兩次采樣值的差值超過最大偏差范圍,認(rèn)為發(fā)生可隨機(jī)干擾,并認(rèn)為后一次采樣值y(n)為非法值,應(yīng)予刪除,刪除y(n)后,可用y(n–1)代替y(n);若未超過所允許的最大偏差范圍,則認(rèn)為本次采樣值有效。下面是限幅濾波程序:(A值可根據(jù)實(shí)際情況調(diào)整,value為有效值,new_value為當(dāng)前采樣值濾波程序返回有效的實(shí)際值)#defineA10charvalue;charfilter(){charnew_value;new_value=get_ad();if((new_value-value>A)||(value-new_value>A))returnvalue;returnnew_value;}九、中位值濾波法
中位值濾波法能有效克服偶然因素引起的波動(dòng)或采樣不穩(wěn)定引起的誤碼等脈沖干擾;
對(duì)溫度液位等緩慢變化的被測(cè)參數(shù)用此法能收到良好的濾波效果,但是對(duì)于流量壓力等快速變化的參數(shù)一般不宜采用中位值濾波法;
基本方法:對(duì)某一被測(cè)參數(shù)連續(xù)采樣n次(一般n取奇數(shù)),然后再把采樣值按大小排列,取中間值為本次采樣值。
下面是中位值濾波程序:#defineN11charfilter(){charvalue_buf[N],count,i,j,temp;for(count=0;count{value_buf[count]=get_ad();delay();}for(j=0;j{for(i=0;i{if(value_buf>value_buf[i+1]){temp=value_buf;value_buf=value_buf[i+1];value_buf[i+1]=temp;}}}returnvalue_buf[(N-1)/2];}十.算術(shù)平均濾波法
算術(shù)平均濾波法適用于對(duì)一般的具有隨機(jī)干擾的信號(hào)進(jìn)行濾波。這種信號(hào)的特點(diǎn)是信號(hào)本身在某一數(shù)值范圍附近上下波動(dòng),如測(cè)量流量、液位;
基本方法:按輸入的N個(gè)采樣數(shù)據(jù),尋找這樣一個(gè)Y,使得Y與各個(gè)采樣值之間的偏差的平方和最小。編寫算術(shù)平均濾波法程序時(shí)嚴(yán)格注意:
一.為了加快數(shù)據(jù)測(cè)量的速度,可采用先測(cè)量數(shù)據(jù)存放在存儲(chǔ)器中,測(cè)完N點(diǎn)后,再對(duì)N個(gè)數(shù)據(jù)進(jìn)行平均值計(jì)算;
二.選取適當(dāng)?shù)臄?shù)據(jù)格式,也就是說采用定點(diǎn)數(shù)還是采用浮點(diǎn)數(shù)。其程序如下所示:#defineN12charfilter(){intsum=0,count;for(count=0;count{sum+=get_ad();delay();}return(char)(sum/N);}十一、遞推平均濾波法
基本方法:采用隊(duì)列作為測(cè)量數(shù)據(jù)存儲(chǔ)器,設(shè)隊(duì)列的長(zhǎng)度為N,每進(jìn)行一次測(cè)量,把測(cè)量結(jié)果放于隊(duì)尾,而扔掉原來隊(duì)首的一個(gè)數(shù)據(jù),這樣在隊(duì)列中始終就有N個(gè)“最新”的數(shù)據(jù)。當(dāng)計(jì)算平均值時(shí),只要把隊(duì)列中的N個(gè)數(shù)據(jù)進(jìn)行算數(shù)平均,就可得到新的算數(shù)平均值。這樣每進(jìn)行一次測(cè)量,就可得到一個(gè)新的算術(shù)平均值。#defineN12charvalue_buf[N],i=0;charfilter(){charcount;intsum=0;value_buf[i++]=get_ad();if(i==N)i=0;for(count=0;countsum=value_buf[count];return(char)(sum/N);}十二、一階滯后濾波法
優(yōu)點(diǎn):對(duì)周期性干擾具有良好的抑制作用,適用于波動(dòng)頻率較高的場(chǎng)合;
缺點(diǎn):相位滯后,靈敏度低.滯后程度取決于a值大小.不能消除濾波頻率高于采樣頻率的1/2的干擾信號(hào)。程序如下:#definea50charvalue;charfilter(){charnew_value;new_value=get_ad();return(100-a)*value+a*new_value;}十三、PID控制算法
在過程控制中,按偏差的比例(P)、積分(I)和微分(D)進(jìn)行控制的PID控制器(亦稱PID調(diào)節(jié)器)是應(yīng)用最為廣泛的一種自動(dòng)控制器;
對(duì)于過程控制的典型對(duì)象──“一階滯后+純滯后”與“二階滯后+純滯后”的控制對(duì)象,PID控制器是一種最優(yōu)控制;
PID調(diào)節(jié)規(guī)律是連續(xù)系統(tǒng)動(dòng)態(tài)品質(zhì)校正的一種有效方法,它的參數(shù)整定方式簡(jiǎn)便,結(jié)構(gòu)改變靈活(PI、PD、…)。一模擬PID調(diào)節(jié)器
PID調(diào)節(jié)器各校正環(huán)節(jié)的作用:比例環(huán)節(jié):即時(shí)成比例地反應(yīng)控制系統(tǒng)的偏差信號(hào)e(t),偏差一旦產(chǎn)生,調(diào)節(jié)器立即產(chǎn)生控制作用以減小偏差;積分環(huán)節(jié):主要用于消除靜差,提高系統(tǒng)的無差度。積分時(shí)間常數(shù)TI越大,積分作用越弱,反之則越強(qiáng);微分環(huán)節(jié):能反應(yīng)偏差信號(hào)的變化趨勢(shì)(變化速率),并能在偏差信號(hào)的值變得太大之前,在系統(tǒng)中引入一個(gè)有效的早期修正信號(hào),從而加快系統(tǒng)的動(dòng)作速度,減小調(diào)節(jié)時(shí)間。
PID調(diào)節(jié)器是一種線性調(diào)節(jié)器,它將給定值r(t)與實(shí)際輸出值c(t)的偏差的比例(P)、積分(I)、微分(D)通過線性組合構(gòu)成控制量,對(duì)控制對(duì)象進(jìn)行控制。
程序片段如下:#include#includetypedefstructPID{doubleSetPoint;//設(shè)定目標(biāo)DesiredvaluedoubleProportion;//比例常數(shù)ProportionalConstdoubleIntegral;//積分常數(shù)IntegralConstdoubleDerivative;//微分常數(shù)DerivativeConstdoubleLastError;//Error[-1]doublePrevError;//Error[-2]doubleSumError;//SumsofErrors}PID;主程序:doublesensor(void){return100.0;}voidactuator(doublerDelta){}voidmain(void){PIDsPID;doublerOut;doublerIn;PIDInit(&sPID);sPID.Proportion=0.5;sPID.Derivative=0.0;sPID.SetPoint=100.0;for(;;){rIn=sensor();rOut=PIDCalc(&sPID,rIn);actuator(rOut);}}十四、開根號(hào)算法
單片機(jī)開平方的快速算法
因?yàn)楣ぷ鞯男枰?,要在單片機(jī)上實(shí)現(xiàn)開根號(hào)的操作。目前開平方的方法大部分是用牛頓迭代法。我在查了一些資料以后找到了一個(gè)比牛頓迭代法更加快速的方法。不敢獨(dú)享,介紹給大家,希望會(huì)有些幫助。1.原理
因?yàn)榕虐娴脑?,用pow(X,Y)表示X的Y次冪,用B[0],B[1],...,B[m-1]表示一個(gè)序列,其中[x]為下標(biāo)。
假設(shè):B[x],b[x]都是二進(jìn)制序列,取值0或1。M=B[m-1]*pow(2,m-1)+B[m-2]*pow(2,m-2)+...+B[1]*pow(2,1)+B[0]*pow(2,0)N=b[n-1]*pow(2,n-1)+b[n-2]*pow(2,n-2)+...+b[1]*pow(2,1)+n[0]*pow(2,0)pow(N,2)=M
(1)N的最高位b[n-1]可以根據(jù)M的最高位B[m-1]直接求得。設(shè)m已知,因?yàn)閜ow(2,m-1)<=M<=pow(2,m),所以pow(2,(m-1)/2)<=N<=pow(2,m/2)如果m是奇數(shù),設(shè)m=2*k+1,那么pow(2,k)<=N<pow(2,1/2+k)<pow(2,k+1),n-1=k,n=k+1=(m+1)/2如果m是偶數(shù),設(shè)m=2k,那么pow(2,k)>N>=pow(2,k-1/2)>pow(2,k-1),n-1=k-1,n=k=m/2所以b[n-1]完全由B[m-1]決定。余數(shù)M[1]=M-b[n-1]*pow(2,2*n-2)
(2)N的次高位b[n-2]可以采用試探法來確定。因?yàn)閎[n-1]=1,假設(shè)b[n-2]=1,則pow(b[n-1]*pow(2,n-1)+b[n-1]*pow(2,n-2),2)=b[n-1]*pow(2,2*n-2)+(b[n-1]*pow(2,2*n-2)+b[n-2]*pow(2,2*n-4)),然后比較余數(shù)M[1]是否大于等于(pow(2,2)*b[n-1]+b[n-2])*pow(2,2*n-4)。這種比較只須根據(jù)B[m-1]、B[m-2]、...、B[2*n-4]便可做出判斷,其余低位不做比較。若M[1]>=(pow(2,2)*b[n-1]+b[n-2])*pow(2,2*n-4),則假設(shè)有效,b[n-2]=1;余數(shù)M[2]=M[1]-pow(pow(2,n-1)*b[
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝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ù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 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-2030教材輔導(dǎo)類書籍行業(yè)發(fā)展分析及競(jìng)爭(zhēng)格局與投資戰(zhàn)略研究咨詢報(bào)告
- 中國(guó)建筑門窗密封條市場(chǎng)耐候性測(cè)試標(biāo)準(zhǔn)及替代材料與供應(yīng)鏈報(bào)告
- 中國(guó)建筑財(cái)稅行業(yè)市場(chǎng)稅務(wù)籌劃策略及成本管控與營(yíng)改增影響報(bào)告
- 中國(guó)建筑節(jié)能玻璃綠色認(rèn)證體系與碳交易機(jī)制關(guān)聯(lián)性分析報(bào)告
- 中國(guó)建筑節(jié)能改造政策對(duì)LonWorks市場(chǎng)的促進(jìn)作用評(píng)估
- 道路交通安全評(píng)估方案
- 中國(guó)建筑工程機(jī)械行業(yè)售后服務(wù)與客戶關(guān)系管理報(bào)告
- 中國(guó)建筑工程機(jī)械行業(yè)區(qū)域市場(chǎng)差異化發(fā)展研究報(bào)告
- 2026年網(wǎng)絡(luò)安全政策與法律解析測(cè)試題
- 污水處理廠運(yùn)營(yíng)管理方案
- 工廠網(wǎng)絡(luò)設(shè)計(jì)方案
- 福建省泉州市2023-2024學(xué)年高一上學(xué)期期末教學(xué)質(zhì)量監(jiān)測(cè)政治試題
- 日文常用漢字表
- JCT947-2014 先張法預(yù)應(yīng)力混凝土管樁用端板
- QC003-三片罐206D鋁蓋檢驗(yàn)作業(yè)指導(dǎo)書
- 高血壓達(dá)標(biāo)中心標(biāo)準(zhǔn)要點(diǎn)解讀及中心工作進(jìn)展-課件
- 某經(jīng)濟(jì)技術(shù)開發(fā)區(qū)突發(fā)事件風(fēng)險(xiǎn)評(píng)估和應(yīng)急資源調(diào)查報(bào)告
- 混凝土質(zhì)量缺陷成因及預(yù)防措施1
- GB/T 28288-2012足部防護(hù)足趾保護(hù)包頭和防刺穿墊
- GB/T 15087-1994汽車牽引車與全掛車機(jī)械連接裝置強(qiáng)度試驗(yàn)
- GB/T 10922-200655°非密封管螺紋量規(guī)
評(píng)論
0/150
提交評(píng)論