一、計數、求和、求階乘等簡單算法
此類問題都要使用循環,要注意根據問題確定循環變量的初值、終值或結束條件,更要注意用來表示計數、和、階乘的變量的初值。
例:用隨機函數產生 100 個[0, 99]范圍內的隨機整數,統計個位上的數字分別為 1, 2, 3, 4,5, 6, 7, 8, 9, 0 的數的個數并打印出來。
本題使用數組來處理,用數組 a[100]存放產生的確 100 個隨機整數,數組 x[10]來存放個位上的數字分別為 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 的數的個數。即個位是 1 的個數存放在 x[1]中,個位是2 的個數存放在 x[2]中, ……個位是 0 的個數存放在 x[10]。
---------------------------------------------------------------------
void main()
{ int a[101],x[11],i,p;
for(i=0;i<=11;i++)
x[i]=0;
for(i=1;i<=100;i++)
{ a[i]=rand() % 100;
printf("%4d",a[i]);
if(i%10==0)printf("\n");
}
for(i=1;i<=100;i++)
{ p=a[i]%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\n",p,x[i]);
}
printf("\n");
}
---------------------------------------------------------------------
二、求兩個整數的大公約數、小公倍數
分析: 求大公約數的算法思想: (小公倍數=兩個整數之積/大公約數)
(1) 對于已知兩數 m, n,使得 m>n;
(2) m 除以 n 得余數 r;
(3) 若 r=0,則 n 為求得的大公約數,算法結束;否則執行(4);
(4) m←n, n←r,再重復執行(2)。
例如: 求 m=14 ,n=6 的大公約數. m n r
14 6 2
6 2 0
---------------------------------------------------------------------
void main()
{ int nm,r,n,m,t;
printf("please input two numbers:\n");
scanf("%d,%d",&m,&n);
nm=n*m;
if (m<n)
{ t=n; n=m; m=t; }
r=m%n;
while (r!=0)
{ m=n; n=r; r=m%n; }
printf("大公約數:%d\n",n);
printf("小公倍數:%d\n",nm/n);
}
---------------------------------------------------------------------
三、判斷素數
只能被 1 或本身整除的數稱為素數 基本思想:把 m 作為被除數,將 2—INT()作為除數,
如果都除不盡, m 就是素數,否則就不是。(可用以下程序段實現)
---------------------------------------------------------------------
void main()
{ int m,i,k;
printf("please input a number:\n");
scanf("%d",&m);
k=sqrt(m);
for(i=2;i<k;i++)
if(m%i==0) break;
if(i>=k)
printf("該數是素數");
else
printf("該數不是素數");
}
將其寫成一函數,若為素數返回 1,不是則返回 0
int prime( m%)
{int i,k;
k=sqrt(m);
for(i=2;i<k;i++)
if(m%i==0) return 0;
return 1;
}
---------------------------------------------------------------------
四、驗證哥德巴赫猜想
(任意一個大于等于 6 的偶數都可以分解為兩個素數之和)
基本思想: n 為大于等于 6 的任一偶數,可分解為 n1 和 n2 兩個數,分別檢查 n1 和 n2 是否為素數,
如都是,則為一組解。如 n1不是素數,就不必再檢查 n2是否素數。先從 n1=3開始,檢驗 n1和 n2 ( n2=N-n1)
是否素數。然后使 n1+2 再檢驗 n1、 n2 是否素數, … 直到 n1=n/2 為止。
利用上面的 prime 函數,驗證哥德巴赫猜想的程序代碼如下:
--------------------------------------------------------------------
#include "math.h"
int prime(int m)
{ int i,k;
k=sqrt(m);
for(i=2;i<k;i++)
if(m%i==0) break;
if(i>=k)
return 1;
else
return 0;
}
main()
{ int x,i;
printf("please input a even number(>=6):\n");
scanf("%d",&x);
if (x<6||x%2!=0)
printf("data error!\n");
else
for(i=2;i<=x/2;i++)
if (prime(i)&′(x-i))
{
printf("%d+%d\n",i,x-i);
printf("驗證成功!");
break;
} }
--------------------------------------------------------------------
五、排序問題
1.選擇法排序(升序)
基本思想:
1)對有 n 個數的序列(存放在數組 a(n)中),從中選出小的數,與第 1 個數交換位置;
2)除第 1 個數外,其余 n-1 個數中選小的數,與第 2 個數交換位置;
3)依次類推,選擇了 n-1 次后,這個數列已按升序排列。
程序代碼如下:
----------------------------------------------------------------
void main()
{ int i,j,imin,s,a[10];
printf("\n input 10 numbers:\n");
for(i=0;i<10;i++)
scanf("%d",&a[i]);
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[i]; a[i]=a[imin]; a[imin]=s; }
printf("%d\n",a[i]);
} }
------------------------------------------------------------------
2.冒泡法排序(升序)
基本思想: (將相鄰兩個數比較,小的調到前頭)
1)有 n 個數(存放在數組 a(n)中),第一趟將每相鄰兩個數比較,小的調到前頭,經 n-1 次兩兩
相鄰比較后,大的數已“沉底”,放在后一個位置,小數上升“浮起”;
2)第二趟對余下的 n-1 個數(大的數已“沉底”)按上法比較,經 n-2 次兩兩相鄰比較后得次大的
數;
3)依次類推, n 個數共進行 n-1 趟比較,在第 j 趟中要進行 n-j 次兩兩比較。
程序段如下---------------------------------------------------------------------
void main()
{ int a[10];
int i,j,t;
printf("input 10 numbers\n");
for(i=0;i<10;i++)
scanf("%d",&a[i]);
printf("\n");
for(j=0;j<=8;j++)
for(i=0;i<9-j;i++)
if(a[i]>a[i+1])
{t=a[i];a[i]=a[i+1];a[i+1]=t;}
printf("the sorted numbers:\n");
for(i=0;i<10;i++)
printf("%d\n",a[i]);
}
-------------------------------------------------------------------
3.合并法排序(將兩個有序數組 A、 B 合并成另一個有序的數組 C,升序)
基本思想:
1)先在 A、 B 數組中各取第一個元素進行比較,將小的元素放入 C 數組;
2)取小的元素所在數組的下一個元素與另一數組中上次比較后較大的元素比較,重復上述比較過
程,直到某個數組被先排完;
3)將另一個數組剩余元素抄入 C 數組,合并排序完成。
程序段如下:
-------------------------------------------------------------------
void main()
{ int a[10],b[10],c[20],i,ia,ib,ic;
printf("please input the first array:\n");
for(i=0;i<10;i++)
scanf("%d",&a[i]);
for(i=0;i<10;i++)
scanf("%d",&b[i]);
printf("\n");
ia=0;ib=0;ic=0;
while(ia<10&&ib<10)
{ if(a[ia]<b[ib])
{ 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\n",c[i]);
}
-------------------------------------------------------------------
六、查找問題
1. ①順序查找法(在一列數中查找某數 x)
基本思想:一列數放在數組 a[1]---a[n]中,待查找的數放在 x 中,把 x 與 a 數組中的元素從頭
到尾一一進行比較查找。用變量 p 表示 a 數組元素下標, p 初值為 1,使 x 與 a[p]比較,如果 x 不等于
a[p],則使 p=p+1,不斷重復這個過程;一旦 x 等于 a[p]則退出循環;另外,如果 p 大于數組長度,循
環也應該停止。(這個過程可由下語句實現)
--------------------------------------------------------------------
void main()
{ int a[10],p,x,i;
printf("please input the array:\n");
for(i=0;i<10;i++)
scanf("%d",&a[i]);
printf("please input the number you want find:\n");
scanf("%d",&x);
printf("\n");
p=0;
while(x!=a[p]&&p<10)
p++;
if(p>=10)
printf("the number is not found!\n");
else
printf("the number is found the no%d!\n",p);
}
--------------------------------------------------------------------
思考:將上面程序改寫一查找函數 Find,若找到則返回下標值,找不到返回-1
②基本思想:一列數放在數組 a[1]---a[n]中,待查找的關鍵值為 key,把 key 與 a 數組中的元素從頭到尾一一進行比較查找,若相同,查找成功,若找不到,則查找失敗。 (查找子過程如下。 index:存放找到元素的下標。 )
------------------------------------------------------------------
void main()
{ int a[10],index,x,i;
printf("please input the array:\n");
for(i=0;i<10;i++)
scanf("%d",&a[i]);
printf("please input the number you want find:\n");
scanf("%d",&x);
printf("\n");
index=-1;
for(i=0;i<10;i++)
if(x==a[i])
{ index=i; break;
}
if(index==-1)
printf("the number is not found!\n");
else
printf("the number is found the no%d!\n",index);
}