C程序设计的常用算法汇编
一、简单数值类算法
此类问题都要使用循环,要注意根据问题确定循环变量的初值、终值或结束条件,更要注意用来表示计数、和、阶乘的变量的初值。
1、 求阶乘
下列程序用于求n的阶乘.在累乘之前,
一定要将用于存放乘积的变量的值初始化为1.
long func(int n)
{
int i;
long t=1;
for(i=2;i<=n;i++)
t*=i;
return t;
}
printf("\n");
}
2、求回文数的函数
int hws(int a) {int c=0; while(a>0) { c=c*10+a%10; a/=10; } return(c); }
|
3、 整数拆分问题:把一个整数各个位上的数字存到数组中
(1)确定3位数 (2)不确定数字位数,
利用数组存储数字 利用变量存储数字 数组定义足够大
int split(int n, int a[10 ]) {int i; for(i=0;n!=0; i++) { a[i]=n%10; n=n/10; } return i; /*返回数字个数*/ }
|
a=n/100; b=n/10%10; c=n%10; |
{int i;
for(i=N-1;n!=0; i--)
{ a[i]=n%10;
n=n/10;
}
}
4、求整数的因子之和
long factor(int n)
{int i;
long sum=0;
for(i=1;i<=n;i++)
if(n%i= =0)
sum+=i;
return sum;
}
注意:因子包括1和自身。
二、求两个整数的最大公约数、最小公倍数
分析:求最大公约数的算法为辗转相除法。(最小公倍数=两个整数之积/最大公约数)
求最大公约数的算法步骤:
(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 { 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); } 将其写成一函数,返回最大公约数。 int gcd(int m,int n) { int t,r; if(m r=m%n; while(r!=0) { m=n; n=r; r=m%n; } return n; } 如果求最小公倍数,其函数形式稍作调整: int gcd(int m,int n) { int a=m, b=n; int t,r; if(m r=m%n; while(r!=0) { m=n; n=r; r=m%n; } return (a*b)/n; } 三、判断素数 只能被1和本身整除的正整数称为素数。 基本思想:在判断数m是否为素数时,首先把m作为被除数,将2—sqrt(m)的所有数字依次作为除数,去除m,只要有一个数能将m整除,则m不是素数;否则,如果都除不尽,则m就是素数。(可用以下程序段实现) #include void main() { int m,i,k; printf("please input a number:\n"); scanf("%d",&m); k=sqrt(m); /*使用此函数一定要加头文件#include for(i=2;i<=k;i++) if(m%i==0) break; if(i>k) printf("该数是素数"); else printf("该数不是素数"); } 将其写成一函数,若为素数返回1,不是则返回0 int prime( int m) {int i,k; if(m==1) return 0; for(i=2;i<=k-1;i++) if(m%i==0) return 0; return 1; } 四、求最值 例如求最小值算法思想: 定义变量min用于存放当前所有找到的最小数,a为已知数组。算法步骤如下: 1)在min中存放第1个数,比较从数组中的第二个元素开始。 2)数组a中每个元素依次与min中的数组相比,小者放入min中。 3)比较完数组的最后一个元素,算法结束。Min中数为所求。 程序如下: 求最大值: max=a[0]; for(i=0;i if(a[i]>max) max=a[i]; {int i,min; min=a[0]; for(i=0;i if(a[i] return min; } main() { int a[10]={12,45,7,8,96,4,10,48,2,46},i,min; for(i=0;i<10;i++) printf(“%3d”,a[i]); printf(“\n”); min=minvalue(a,10); printf(“the result is:%d”, min); } 五、排序问题 1.选择法排序(升序) 基本思想: 1)对有n个数的序列(存放在数组a(n)中),从中选出最小的数,与第1个数交换位置; 2)除第1 个数外,其余n-1个数中选最小的数,与第2个数交换位置; 3)依次类推,选择了n-1次后,这个数列已按升序排列。 自定义函数形式 void sort(int a[], int n) { int i,j,imin,s; for(i=0;i { imin=i; for(j=i+1;j if(a[imin]>a[j]) imin=j; if(i!=imin) {s=a[i]; a[i]=a[imin]; a[imin]=s; } } } 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() 自定义函数形式: void sort(int a[], int n) { int i,j,t; 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;} } 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]
{ 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]; ib++;ic++; } for(i=0;i<20;i++) printf("%d\n",c[i]); } 六、查找问题 1.①顺序查找法(在一列数中查找某数x) 思考:将上面程序改写一查找函数Find,若找到则返回下标值,找不到返回-1 ②基本思想:一列数放在数组a[1]---a[n]中,待查找的关键值为key,把key与a数组中的元素从头到尾一一进行比较查找,若相同,查找成功,若找不到,则查找失败。(查找子过程如下。index:存放找到元素的下标。) 采用另外一种方法自定义函数,若找到则返回下标值,找不到返回-1: int seek(int a[],int n, int x) { int p=0; while(x!=a[p]&&p p++; if(p>=n) return -1; else return p; } { 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); } 2.折半查找法(只能对有序数列进行查找) 基本思想:设n个有序数(从小到大)存放在数组a[1]----a[n]中,要查找的数为x。用变量bot、top、mid 分别表示查找数据范围的底部(数组下界)、顶部(数组的上界)和中间,mid=(top+bot)/2,折半查找的算法如下: (1)x=a(mid),则已找到退出循环,否则进行下面的判断;
int minvalue(int a[],int n)
程序代码如下:
{ int a[10];
void main()