[学习资料] C语言经典算法

[复制链接]
1885|14
 楼主| dspmana 发表于 2023-3-26 20:56 | 显示全部楼层 |阅读模式
一、冒泡排序

随机输入十个数,按从大到小排序

int main()    -----------冒泡排序{        int a[10];        int i,j,t;        printf("input 10 nimber:\n");        for(i=0;i<10;i++)        {                scanf("%d",&a);        }        printf("\n");        for(j=0;j<9;j++)                for(i=0;i<9-j;i++)                        {                                if(a>a[i+1])                                {t=a;a=a[i+1];a[i+1]=t;}                        }        printf("sorted number:\n");        for(i=0;i<10;i++)                printf("%d ",a);        printf("\n");        return 0;}

先用for循环,循环打印十个数赋值给a,再通过两个嵌套for循环,第一个for循环实现循环9趟

第二个for循环实现在每一趟中比较9-j次,为什么是9-j:第一次循环完成后,第一个数成功安排在第一位,那么接下来的每一次都不用处理这第一个数,因此还剩下9-1个数需要对比,所以在进行第二趟循环时只需要比较8次,以此类推。最后对数组a遍历输出               

二、斐波那契函数问题1、普通解法

求斐波那契数列的前40个数,斐波那契函数的变化规律

F1=1,F2=1,Fn=Fn-1+Fn-2(n>=3)

#include<stdio.h>int main(){        int f1=1,f2=1,i;        for(i=1;i<=20;i++)        {                printf("%12d %12d",f1,f2);                if(i%2==0)printf("\n");                f1=f1+f2;                f2=f2+f1;        }        return 0;}

主要关键代码为f1=f1+f2;f2=f2+f1;实现依次累加

在解决这个问题时出现打印结果的排列并不是预期的每四行输出一个换行符,1,1两个初始值单独换行,最后发现i是从0开始循环,所以当i=0时也就是第一次进入循环0%2==0,因此发生了换行操作。

2、用数组实现斐波那契函数#include<stdio.h>int main(){        int a[20]={1,1};        int i;        for(i=2;i<20;i++)                a=a[i-1]+a[i-2];        for(i=0;i<20;i++)        {                if(i%3==0)printf("\n");                printf("%12d",a);        }        return 0;}

对数组的前两个赋初值1,1,for循环从第三个数开始,最后依次遍历数组a的值

再次出现打印结果排列出现问题,原因是在if判断语句时,写在了打印a语句的下方,导致了程序先打印后才进行判断

三、猴子吃桃问题

一只猴子第一天摘了n个桃,当即吃了一半又多吃了一个,第二天又吃了一半再多吃一个,直到第十天早上想吃时只剩下1个,问第一天摘了多少桃?

int main()       ------猴子吃桃问题{        int i,m=1,sum;        for(i=1;i<=9;i++)        {                m=2*(m+1);                        }        printf("%d",md);}

第一天个数为n,第二天为n=n/2-1,直到第九天n/2-1=1,因此我们可以进行逆向思考,从第九天开始初值为1,变化量为2(n+1),对变化量循环九次最终得到n。

四、素数问题

求100-200之间所有的素数

#include<math.h>        100-200之间的素数int main(){        int i,j=0,m,n;        for(n=101;n<=200;n+=2)                {                m=sqrt(n);                for(i=2;i<=m;i++)                        if(n%i==0)                                break;                        if(i>=m)                        {                                printf("%d ",n);                                j=j+1;                        }                        if(j%10==0)                                printf("\n");        }        return 0;}

判断一个数是否为素数,只需要判断这个数n能否被2~√n整除,如果不能整除那么循环不会停止直到最后一个数判断为之,循环结束后i++,而循环条件是i<√n,如果n不是素数,那么i一定大于√n。

五、最大公约数与最小公倍数1、使用for循环实现
  1. #include<stdio.h>
  2. int main()
  3. {
  4.         int m,n,temp,i;
  5.         scanf("%d %d",&m,&n);
  6.         if(m<n)
  7.         {
  8.                 temp=m;
  9.                 m=n;
  10.                 n=temp;
  11.         }
  12.         for(i=n;i>0;i--)
  13.         {
  14.                 if(m%i==0&&n%i==0)
  15.                 {
  16.                         printf("Max=%d\n",i); //最大公倍数
  17.                        
  18.                         break;
  19.                 }
  20.                
  21.         }
  22.         printf("Min=%d\n",m*n/i); //最小公约数
  23.         return 0;
  24. }

先判断两个输入值的大小,将两个数按从大到小的顺序互换值,将两者之间较小的数赋值给i

进入for循环,例如,6和10,将6赋值给i,进入循环,6%6=1,10%6=4,i-- == 5,进入下一次循环,直到m,n%i==0时得到最小公约数,最大公倍数:只要求出最小公约数,然后将两数之积除以最小公约数得到

2、使用辗转相除法
  1. int main()
  2. {
  3.         int a,b;
  4.         int t;
  5.         int num1,num2;
  6.         scanf("%d %d",&num1,&num2);
  7.         a=num1;
  8.         b=num2;
  9.         while(b!=0)
  10.         {
  11.                 t=a%b;
  12.                 a=b;
  13.                 b=t;
  14.        
  15.         }
  16.         printf("Max=%d\n",a);     //最大公约数
  17.         printf("%d",num1*num2/a); //最小公倍数
  18.         return 0;
  19. }

采用辗转相除法求最小公倍数必须将输入的值赋给另一个变量,如果直接使用公式a*b/a会报错无法输出结果

在while循环中 将a%b的余数赋值给t,再将b赋值给a,t赋值给b,此时b为余数,进入下一次循环直到余数b为零,例如,输入a=6,b=8;先进行t=a%b==6%8==6,a=b=8,b=t=6进入下一次循环

t=a%b==8%6==2,a=b=6,b=t=2;进入下一次循环t=a%b==6%2==0 此时b为0结束循环。

六、水仙花问题

打印100-999中所有的水仙花数

  1. int main()
  2. {
  3.         int i,j,m,n,num;
  4.         for(i=100;i<1000;i++)
  5.         {
  6.                 j = i/100;       //百位
  7.                 m = i/10%10;     //十位
  8.                 n = i%10;        //个位
  9.                 num = j*j*j+m*m*m+n*n*n;
  10.                 if(num == i)
  11.                         printf("%-5d",i);   
  12.         }
  13.        
  14.         return 0;
  15. }

其中%-5d表示的是控制五个字符格式输出,左对齐

%-md:输出格式为整形,长度为m(输出最小长度),左对齐;

七、分解质因数问题

将一个正整数分解质因数,例如将30分解成2*3*5

  1. int main()
  2. {
  3.         int i,m;
  4.         scanf("%d",&m);
  5.         printf("%d=",m);
  6.         for(i=2;i<=m;i++)
  7.         {
  8.                 while(m!=i)
  9.                 {
  10.                         if(m%i == 0)
  11.                         {
  12.                                 printf("%d*",i);
  13.                                 m=m/i;
  14.                         }
  15.                         else
  16.                                 break;       
  17.                 }
  18.         }
  19.         printf("%d",m);
  20.         return 0;
  21. }

问题思路:先用for循环,从2开始循环到这个数m为止,如果循环i等于了m说明循环已经遍历完成跳出循环,所以以这个为条件进行while循环,当i不等于这个数时,如果m%i==0说明i可以除尽m则i是m的一个因子,打印这个i,在对整数继续进行循环遍历m=m/i,直到i=m结束。

八、完数问题

找出1000以内的所有完数

一个数如果恰好等于它的因子之和,这个数就称为完数,例如6=1*2*3而6=1+2+3,所以6是完数


  1. int main()
  2. {
  3.         int i=0;
  4.         int arr[100]={0};
  5.         for(i=2;i<=1000;i++)
  6.                 {
  7.                         int m=0,sum=0;
  8.                         int k=0,j=0;
  9.                         for(j=1;j<i;j++)
  10.                                 {
  11.                                         if(i%j==0)
  12.                                         {
  13.                                                 arr[k]=j;
  14.                                                 k++;
  15.                                         }       
  16.                                 }
  17.                                 for(m=0;m<k;m++)
  18.                                                 sum+=arr[m];
  19.                                 if(sum==i)
  20.                                                 printf("%d\n",i);
  21.                 }
  22.         return 0;
  23. }

问题分析: 先找出每个数的因子并依次存放在数组arr[ ]中,再对数组进行遍历,依次打印并求和

如果和等于这个数则输出。

注:int m=0,sum=0;int k=0,j=0;这四个变量的赋值必须在第一个for循环中,作用是依次找出每个数的因子并判断,一个数判断结束后,进入到下一个数时再对这四个变量重新赋初值

九、求a+aa+aaa+aaaa……的值

例如a=2,n=4,求2+22+222+2222的值

  1. int main()
  2. {
  3.         int i=1,a,n,m;
  4.         long int count = 0,num = 0;
  5.         scanf("%d,%d",&a,&n);
  6.         while(i<=n)
  7.         {
  8.                 num += a;
  9.                 count += num;
  10.                 a = a*10;
  11.                 ++i;
  12.         }
  13.         printf("%d\n",count);
  14.         return 0;
  15. }

问题分析:求解此类问题关键是求出每一项的值,而每一项的值为对(a+a*10)的循环,设每一项初值为0,总和为0,第一次进入循环第一项的值为num=num+a;num初值为0,所以第一项为a,此时num为a,总数count为a,a=a*10进入下一次循环,num=a+a*10,count=a+(a+a*10),再进入下一次循环直到n为止。

十、小球落地弹起问题

一小球从100米高度自由落下,每次落地后反弹回原高度的一半再落下,求它在第十次落地时共经过多少米?第十次反弹多高?

  1. int main()
  2. {
  3.         int i;
  4.         float h=100.0,s=h/2;
  5.         for(i=1;i<=10;i++)
  6.         {
  7.                 h = h + 2*s;
  8.                 s = s/2;
  9.         }
  10.         printf("h=%f,s=%f\n",h,s);
  11.         return 0;
  12. }

十一、打擂台算法

有一个3*4的矩阵,要求编程求出矩阵中最大的元素,以及最大元素的位置

  1. int main()
  2. {
  3.         int a[3][4]={{12,14,17,18},{4,67,3,2},{4,58,1,7}};
  4.         int row,colum,i,j,max;
  5.         max=a[0][0];
  6.         for(i=0;i<3;i++)
  7.                 for(j=0;j<4;j++)
  8.                         {
  9.                                 if(a[i][j]>max)
  10.                                         {
  11.                                                 max=a[i][j];
  12.                                                 row=i;
  13.                                                 colum=j;       
  14.                                         }       
  15.                         }       
  16.         printf("%d\n%d\n%d\n",max,i,j);
  17.         return 0;
  18. }

问题分析:首先定义最大值为数组初值[0][0],再用冒泡排序,在三行四列中进行循环,使用if判断如果a[j]>max,则将a[j]的值赋给max,将i,j值分别存储。

十二、switch分级问题

给出一个百分制成绩,要求输出成绩等级'A','B','C','D','E'。90分以上为A,80~89分为B,70~79分为C,60~69分为D,60分以下为E。

  1. int main()
  2. {
  3.         int sc,i;
  4.         printf("please input you score:");
  5.         scanf("%d",&sc);
  6.         i=sc/10;
  7.         printf("your score is:");
  8.         switch(i)
  9.         {
  10.                 case 1:
  11.                 case 2:
  12.                 case 3:
  13.                 case 4:
  14.                 case 5:printf("E");break;
  15.                 case 6:printf("D");break;
  16.                 case 7:printf("C");break;
  17.                 case 8:printf("B");break;
  18.                 case 9:
  19.                 case 10:printf("A");break;
  20.         }

  21.         return 0;
  22. }

注意:switch语句括号中的数据必须是整数类型包括字符型。

十三、求数组中最大元素的下标,并输出存储的值
  1. int fun(int *s,int t,int *k)
  2. {
  3.     int i;
  4.     *k = 0;
  5.     /* *k所指的数为下标值 */
  6.     for(i=0;i<t;i++)
  7.         if(s[*k]<s[i])
  8.             *k=i;
  9.     /*找到数组的最大元素,把该元素的下标赋给k所指的数*/
  10.     return s[*k]
  11.    
  12. }

十四、阶乘计算


  1. float fun(int m,int n)
  2. {
  3.     float p1,p2,p3,p4;
  4.     /*m的阶乘*/
  5.     for(i=1;i<=m;i++)
  6.         p1 *= i;
  7.     /*n的阶乘*/
  8.     for(i=1;i<=n;i++)
  9.         p2 *= i;
  10.     /*m-n的阶乘*/
  11.     for(i=1;i<=m-n;i++)
  12.         p3 *= i;
  13.     p4 = p1/(p2*p3);
  14.     return p4;
  15. }


maqianqu 发表于 2023-4-9 14:11 | 显示全部楼层
介绍几个经典的C语言算法              
mattlincoln 发表于 2023-5-13 12:40 | 显示全部楼层
这些算法都是经典的排序和搜索算法
loutin 发表于 2023-5-13 12:55 | 显示全部楼层
有什么经典的c语言算法书推荐一下吗
jkl21 发表于 2023-5-14 20:28 | 显示全部楼层
C语言的遍历算法               
louliana 发表于 2023-5-14 21:27 | 显示全部楼层
经典推荐书籍介绍:《微型计算机原理及应用》(
tifmill 发表于 2023-5-14 21:59 | 显示全部楼层
数据结构与算法分析——c语言描述不错。
linfelix 发表于 2023-5-14 22:09 | 显示全部楼层
c语言常用算法有哪些              
uytyu 发表于 2023-5-18 10:49 | 显示全部楼层
需要一些c语言写得经典滤波,pid控制,模糊控制的算法。
febgxu 发表于 2023-5-18 11:12 | 显示全部楼层
冒泡排序算法:比较相邻的元素。如果第一个比第二个大,就交换它们两个;对每一对相邻元素做同样的工作,从开始到结尾,最后的元素即为最大值。
gygp 发表于 2023-5-18 14:01 | 显示全部楼层
在实际开发中,需要根据具体问题和应用场景选择合适的算法,并进行优化和调试
内政奇才 发表于 2023-5-19 16:16 来自手机 | 显示全部楼层
哪几种算法是最常用的了
uptown 发表于 2023-5-21 09:56 | 显示全部楼层
冒泡排序算法:比较相邻的元素。如果第一个比第二个大,就交换它们两个;对每一对相邻元素做同样的工作,从开始到结尾,最后的元素即为最大值。
iyoum 发表于 2023-5-21 10:14 | 显示全部楼层
在实际开发中,需要根据具体问题和应用场景选择合适的算法,并进行优化和调试
pentruman 发表于 2023-5-21 10:30 | 显示全部楼层
需要一些c语言写得经典滤波,pid控制,模糊控制的算法。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

45

主题

2872

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部