✅ 操作成功!

c语言算法

发布时间:2023-06-07 作者:admin 来源:文学

c语言算法

c语言算法

果蔗-平行线的判定

2023年2月22日发(作者:海豚肉)

C语言常用算法一、基本算法1.交换(两量交换借助第三者)

例1、任意读入两个整数,将二者的值交换后输出。main()

{inta,b,t;scanf("%d%d",&a,&b);printf("%d,%dn",a,b);t=a;

a=b;b=t;printf("%d,%dn",a,b);}【解析】程序中加粗部分为算

法的核心,如同交换两个杯子里的饮料,必须借助第三个空杯

子。假设输入的值分别为3、7,则第一行输出为3,7;第二

行输出为7,3。其中t为中间变量,起到“空杯子”的作用。注

意:三句赋值语句赋值号左右的各量之间的关系!【应用】例

2、任意读入三个整数,然后按从小到大的顺序输出。main()

{inta,b,c,t;scanf("%d%d%d",&a,&b,&c);/*以下两个if语句使

得a中存放的数最小*/if(a>b){t=a;a=b;b=t;}if(a>c){t=a;a=c;

c=t;}/*以下if语句使得b中存放的数次小*/if(b>c){t=b;b=c;

c=t;}printf("%d,%d,%dn",a,b,c);}2.累加ss+累加算法的要领

是形如“=A”的累加式,此式必须出现在循环中才能被反复执行,

从而实现累加功能。“A”通常是有规律变化的表达式,s在进入

循环前必须获得合适的初值,通常为0。例1、求

1+2+3+„„+100的和。main(){inti,s;s=0;i=1;while(i<=100)

{s=s+i;/*累加式*/i=i+1;/*特殊的累加式*/}

printf("1+2+3+...+100=%dn",s);}【解析】程序中加粗部分为累

加式的典型形式,赋值号左右都出现的变量称为累加器,其中

“i=i+1”为特殊的累加式,每次累加的值为1,这样的累加器又

称为计数器。

C语言常用算法3.累乘累乘算法的要领是形如“s=s*A”的累乘

式,此式必须出现在循环中才能被反复执行,从而实现累乘功

能。“A”通常是有规律变化的表达式,s在进入循环前必须获得

合适的初值,通常为1。例1、求10![分析]10!

=1×2×3ׄ„×10main(){inti;longc;c=1;i=1;while(i<=10)

{c=c*i;/*累乘式*/i=i+1;}printf("1*2*3*...*10=%ldn",c);}

二、非数值计算常用经典算法1.穷举也称为“枚举法”,即将

可能出现的每一种情况一一测试,判断是否满足条件,一般采

用循环来实现。例1、用穷举法输出所有的水仙花数(即这样

的三位正整数:其每位数位上的数字的立方和与该数333相等,

比如:1+5+3=153)。[法一]main(){intx,g,s,b;

for(x=100;x<=999;x++){g=x%10;s=x/10%10;b=x/100;

if(b*b*b+s*s*s+g*g*g==x)printf("%dn",x);}}【解析】此方法是

将100到999所有的三位正整数一一考察,即将每一个三位正

整数的个位数、十位数、百位数一一求出(各数位上的数字的

提取算法见下面的“数字处理”),算出三者的立方和,一旦与原

数相等就输出。共考虑了900个三位正整数。[法二]main()

{intg,s,b;for(b=1;b<=9;b++)for(s=0;s<=9;s++)

for(g=0;g<=9;g++)if(b*b*b+s*s*s+g*g*g==b*100+s*10+g)

printf("%dn",b*100+s*10+g);}【解析】此方法是用1到9做百

位数字、0到9做十位和个位数字,将组成的三位正整数与每

一组的三个数的立方和进行比较,一旦相等就输出。共考虑了

900个组合(外循环单独执行的次数为9,两个内循环单独执行

的次数分别为10次,故if语句被执行的次数为9×10×10=900),

即900个三位正整数。与法一判断的次数一样。

C语言常用算法2.排序(1)冒泡排序(起泡排序)假设要

对含有n个数的序列进行升序排列,冒泡排序算法步骤是:

①从存放序列的数组中的第一个元素开始到最后一个元素,依

次对相邻两数进行比较,若前者大后者小,则交换两数的位置;

②第①趟结束后,最大数就存放到数组的最后一个元素里了,

然后从第一个元素开始到倒数第二个元素,依次对相邻两数进

行比较,若前者大后者小,则交换两数的位置;③重复步骤

①n-1趟,每趟比前一趟少比较一次,即可完成所求。例1、

任意读入10个整数,将其用冒泡法按升序排列后输出。

#definen10main(){inta[n],i,j,t;for(i=0;i

scanf("%d",&a[i]);for(j=1;j<=n-1;j++)/*n个数处理n-1趟*/

for(i=0;i<=n-1-j;i++)/*每趟比前一趟少比较一次*/

if(a[i]>a[i+1]){t=a[i];a[i]=a[i+1];a[i+1]=t;}for(i=0;i

printf("%dn",a[i]);}(2)选择法排序选择法排序是相对好理解

的排序算法。假设要对含有n个数的序列进行升序排列,算法

步骤是:①从数组存放的n个数中找出最小数的下标(算法

见下面的“求最值”),然后将最小数与第1个数交换位置;②

除第1个数以外,再从其余n-1个数中找出最小数(即n个数

中的次小数)的下标,将此数与第2个数交换位置;③重复步

骤①n-1趟,即可完成所求。例1、任意读入10个整数,将其

用选择法按升序排列后输出。#definen10main(){int

a[n],i,j,k,t;for(i=0;i

/*处理n-1趟*/{k=i;/*总是假设此趟处理的第一个(即全

部数的第i个)数最小,k记录其下标*/for(j=i+1;j

if(a[j]

for(i=0;i

地掌握此算法,先请了解“有序序列的插入算法”,就是将某数

据插入到一个有序序列后,该序列仍然有序。插入算法参见下

面的“数组元素的插入”。

C语言常用算法例1、将任意读入的整数x插入一升序数列后,

数列仍按升序排列。#definen10main(){inta[n]={-

1,3,6,9,13,22,27,32,49},x,j,k;/*注意留一个空间给待插数*/

scanf("%d",&x);if(x>a[n-2])a[n-1]=x;/*比最后一个数还大就

往最后一个元素中存放*/else/*查找待插位置*/{j=0;

while(ja[j])j++;/*从最后一个数开始直到待插位

置上的数依次后移一位*/for(k=n-2;k>=j;k--)a[k+1]=a[k];

a[j]=x;/*插入待插数*/}for(j=0;j<=n-1;j++)printf("%d

",a[j]);}插入法排序的要领就是每读入一个数立即插入到最终

存放的数组中,每次插入都使得该数组有序。例2、任意读入

10个整数,将其用插入法按降序排列后输出。#definen10

main(){inta[n],i,j,k,x;scanf("%d",&a[0]);/*读入第一个数,直

接存到a[0]中*/for(j=1;j

序插入到数组a中*/{scanf("%d",&x);if(x

比原数列最后一个数还小就往最后一个元素之后存放新读的数

*/else/*以下查找待插位置*/{i=0;while(x

1)i++;/*以下for循环从原最后一个数开始直到待插位置上

的数依次后移一位*/for(k=j-1;k>=i;k--)a[k+1]=a[k];a[i]=x;

/*插入待插数*/}}for(i=0;i

(4)归并排序即将两个都升序(或降序)排列的数据序列

合并成一个仍按原序排列的序列。例1、有一个含有6个数据

的升序序列和一个含有4个数据的升序序列,将二者合并成一

个含有10个数据的升序序列。#definem6#definen4main()

{inta[m]={-3,6,19,26,68,100},b[n]={8,10,12,22};inti,j,k,c[m+n];

C语言常用算法i=j=k=0;while(i

的较小数依次存放到c数组中*/{if(a[i]

else{c[k]=b[j];j++;}k++;}while(i>=m&&j

部存放完毕,将b中余下的数全部存放到c中*/{c[k]=b[j];k++;

j++;}while(j>=n&&i

余下的数全部存放到c中*/{c[k]=a[i];k++;i++;}

for(i=0;i

(即线性查找)顺序查找的思路是:将待查找的量与数组中的

每一个元素进行比较,若有一个元素与之相等则找到;若没有

一个元素与之相等则找不到。例1、任意读入10个数存放到数

组a中,然后读入待查找数值,存放到x中,判断a中有无与

x等值的数。#defineN10main(){inta[N],i,x;for(i=0;i

scanf("%d",&a[i]);/*以下读入待查找数值*/scanf("%d",&x);

for(i=0;i

printf("Found!n");elseprintf("Notfound!n");}(2)折半查找

(即二分法)顺序查找的效率较低,当数据很多时,用二分法

查找可以提高效率。使用二分法查找的前提是数列必须有序。

二分法查找的思路是:要查找的关键值同数组的中间一个元素

比较,若相同则查找成功,结束;否则判别关键值落在数组的

哪半部分,就在这半部分中按上述方法继续比较,直到找到或

数组中没有这样的元素值为止。例1、任意读入一个整数x,

在升序数组a中查找是否有与x等值的元素。#definen10

main(){inta[n]={2,4,7,9,12,25,36,50,77,90};int

x,high,low,mid;/*x为关键值*/scanf("%d",&x);high=n-1;

low=0;mid=(high+low)/2;while(a[mid]!=x&&low

{if(x

C语言常用算法elselow=mid+1;/*修改区间下界*/

mid=(high+low)/2;}if(x==a[mid])

printf("Found%d,%dn",x,mid);elseprintf("Notfoundn");}

三、数值计算常用经典算法:1.级数计算级数计算的关键是

“描述出通项”,而通项的描述法有两种:一为直接法、二为间

接法又称递推法。直接法的要领是:利用项次直接写出通项式;

递推法的要领是:利用前一个(或多个)通项写出后一个通项。

可以用直接法描述通项的级数计算例子有:(1)

1+2+3+4+5+„„(2)1+1/2+1/3+1/4+1/5+„„等等。可以用间接法

描述通项的级数计算例子有:(1)

1+1/2+2/3+3/5+5/8+8/13+„„(2)1+1/2!+1/3!+1/4!+1/5!+„„等

等。(1)直接法求通项例1、求1+1/2+1/3+1/4+1/5+„„+1/100

的和。main(){floats;inti;s=0.0;for(i=1;i<=100;i++)

s=s+1.0/i;printf("1+1/2+1/3+...+1/100=%fn",s);}【解析】

程序中加粗部分就是利用项次i的倒数直接描述出每一项,并

进行累加。注意:因为i是整数,故分子必须写成1.0的形式!

(2)间接法求通项(即递推法)例2、计算下列式子前20项

的和:1+1/2+2/3+3/5+5/8+8/13+„„。[分析]此题后项的分子是

前项的分母,后项的分母是前项分子分母之和。main()

{floats,fz,fm,t,fz1;inti;s=1;/*先将第一项的值赋给累加器

s*/fz=1;fm=2;t=fz/fm;/*将待加的第二项存入t中*/

for(i=2;i<=20;i++){s=s+t;/*以下求下一项的分子分母*/

fz1=fz;/*将前项分子值保存到fz1中*/fz=fm;/*后项分

子等于前项分母*/fm=fz1+fm;/*后项分母等于前项分子、分

母之和*/

C语言常用算法t=fz/fm;}printf("1+1/2+2/3+...=%fn",s);}

下面举一个通项的一部分用直接法描述,另一部分用递推法描

述的级数计算的例子:n21例3、计算级数的值,当通项的

绝对值小于eps时计算停止。n!20#include

floatg(floatx,floateps);main(){floatx,eps;

scanf("%f%f",&x,&eps);printf("n%f,%fn",x,g(x,eps));}float

g(floatx,floateps){intn=1;floats,t;s=1;t=1;do

{t=t*x/(2*n);s=s+(n*n+1)*t;/*加波浪线的部分为直接法描

述部分,t为递推法描述部分*/n++;}while(fabs(t)>eps);

returns;}2.一元非线性方程求根(1)牛顿迭代法牛顿迭代

法又称牛顿切线法:先任意设定一个与真实的根接近的值x作

为第一次近似根,由0x求出f(x),过(x,f(x))点做f(x)的切线,交

x轴于x,把它作为第二次近似根,再由x求出f(x),0000111过(x,

f(x))点做f(x)的切线,交x轴于x,„„如此继续下去,直到足够

接近(比如|x-x|<1e-61120*时)真正的根x为止。而f

'(x)=f(x)/(x-x)所以x=x-f(x)/f'(x)例如,用牛顿

迭代法求下列方程在1.5附近的根:2x-4x+3x-6=0。#include

"math.h"main()

C语言常用算法{floatx,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);printf("%fn",x);}(2)二分法

算法要领是:先指定一个区间[x,x],如果函数f(x)在此区间是

单调变化的,则可以根据f(x)121和f(x)是否同号来确定方程

f(x)=0在区间[x,x]内是否有一个实根;如果f(x)和f(x)同号,则

f(x)21212在区间[x,x]内无实根,要重新改变x和x的值。当确定

f(x)在区间[x,x]内有一个实根后,可121212采取二分法将[x,x]一

分为二,再判断在哪一个小区间中有实根。如此不断进行下去,

直到小区间12足够小为止。具体算法如下:(1)输入x和x

的值。12(2)求f(x)和f(x)。12(3)如果f(x)和f(x)同号说明在

[x,x]内无实根,返回步骤(1),重新输入x和x的值;若

f(x)1212121和f(x)不同号,则在区间[x,x]内必有一个实根,执行

步骤(4)。212(4)求x和x的中点:x=(x+x)/2。12012(5)

求f(x)。0(6)判断f(x)与f(x)是否同号。01①如果同号,则应

在[x,x]中寻找根,此时x已不起作用,用x代替x,用f(x)代替

f(x)。0210101②如果不同号,则应在[x,x]中寻找根,此时x已不

起作用,用x代替x,用f(x)代替f(x)。1020202-5-5(7)判断f(x)

的绝对值是否小于某一指定的值(例如10)。若不小于10,则

返回步骤(4)重0复执行步骤(4)、(5)、(6);否则执行步骤

(8)。(8)输出x的值,它就是所求出的近似根。032例如,

用二分法求方程2x-4x+3x-6=0在(-10,10)之间的根。#include

"math.h"main(){floatx1,x2,x0,fx1,fx2,fx0;do{printf("Enter

x1&x2");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;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.梯形法计算定积分

C语言常用算法bf(x)dx定积分的几何意义是求曲线y=f(x)、

x=a、x=b以及x轴所围成的面积。a可以近似地把面积视为若

干小的梯形面积之和。例如,把区间[a,b]分成n个长度相等的

小区间,每个小区间的长度为h=(b-a)/n,第i个小梯形的面积

为[f(a+(i-1)·h)+f(a+i·h)]·h/2,将n个小梯形面积加起来就得到定

积分的近似值:

根据以上分析,给出“梯形法”求定积分的N-S结构图:

输入区间端点:a,b输入等分数nh=(b-a)/2,s=0i从1到n

si=(f(a+(i-1)*h)+f(a+i*h))*h/2s=s+si输出s上述程序的几何意义

比较明显,容易理解。但是其中存在重复计算,每次循环都要

计算小梯形的上、下底。其实,前一个小梯形的下底就是后一

个小梯形的上底,完全不必重复计算。为此做出如下改进:

矩形法求定积分则更简单,就是将等分出来的图形当作矩形,

而不是梯形。4例如:求定积分的值。

等分数n=1000。0

C语言常用算法#include"math.h"floatDJF(floata,floatb)

{floatt,h;intn,i;floatHSZ(floatx);n=1000;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);}floatHSZ(floatx){return(x*x+3*x+2);}main(){float

y;y=DJF(0,4);printf("%fn",y);}四、其他常见算法1.迭代法

其基本思想是把一个复杂的计算过程转化为简单过程的多次重

复。每次重复都从旧值的基础上递推出新值,并由新值代替旧

值。例如,猴子吃桃问题。猴子第一天摘下若干个桃子,当即

吃了一半,还不过瘾,又多吃了一个。第二天早上又将剩下的

桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩

下的一半零一个。到第10天早上想再吃时,就只剩一个桃子了。

编程求第一天共摘多少桃子。main(){intday,peach;

peach=1;for(day=9;day>=1;day--)peach=(peach+1)*2;

printf("Thefirstday:%dn",peach);}a又如,用迭代法求x=的

根。求平方根的迭代公式是:x=0.5×(x+a/x)n+1nn[算法](1)

设定一个初值x。0(2)用上述公式求出下一个值x。1(3)再

将x代入上述公式,求出下一个值x。12(4)如此继续下去,

直到前后两次求出的x值(x和x)满足以下关系:n+1n-5|x-

x|<10n+1n#include"math.h"main(){floata,x0,x1;

C语言常用算法scanf("%f",&a);x0=a/2;x1=(x0+a/x0)/2;

do{x0=x1;x1=(x0+a/x0)/2;}while(fabs(x0-x1)>=1e-5);

printf("%fn",x1);}2.进制转换(1)十进制数转换为其他进制

数一个十进制正整数m转换成r进制数的思路是,将m不断

除以r取余数,直到商为0时止,以反序输出余数序列即得到

结果。注意,转换得到的不是数值,而是数字字符串或数字串。

例如,任意读入一个十进制正整数,将其转换成二至十六任意

进制的字符串。voidtran(intm,intr,charstr[],int*n){char

sb[]="ABCDEF";inti=0,g;do{g=m%r;str[i]=sb[g];

m=m/r;i++;}while(m!=0);*n=i;}main(){intx,r0;

/*r0为进制基数*/inti,n;/*n中存放生成序列的元素个数*/

chara[50];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",a[i]);

printf("n");}elseexit(0);}(2)其他进制数转换为十进制

数其他进制整数转换为十进制整数的要领是:“按权展开”,例

如,有二进制数101011,则其十543210……a进制形式为

1×2+0×2+1×2+0×2+1×2+1×2=43。若r进制数aa(n位数)转换

成n21n-110十进制数,方法是a×r+……a×r+a×r。n21注意:其他进

制数只能以字符串形式输入。例1、任意读入一个二至十六进

制数(字符串),转换成十进制数后输出。#include"string.h"

#include"ctype.h"

C语言常用算法main(){charx[20];intr,d;gets(x);/*输入

一个r进制整数序列*/scanf("%d",&r);/*输入待处理的进制基

数2-16*/d=Tran(x,r);printf("%s=%dn",x,d);}intTran(char

*p,intr){intd,i,cr;charfh,c;d=0;fh=*p;if(fh=='-')p++;

for(i=0;i='A')

cr=toupper(c)-'A'+10;elsecr=c-'0';d=d*r+cr;}if(fh=='-')

d=-d;return(d);}3.矩阵转置矩阵转置的算法要领是:将一

个m行n列矩阵(即m×n矩阵)的每一行转置成另一个n×m

矩阵的相应列。例1、将以下2×3矩阵转置后输出。即将1

23转置成1445625

36main(){inta[2][3],b[3][2],i,j,k=1;for(i=0;i<2;i++)

for(j=0;j<3;j++)a[i][j]=k++;/*以下将a的每一行转存到b

的每一列*/for(i=0;i<2;i++)for(j=0;j<3;j++)b[j][i]=a[i][j];

for(i=0;i<3;i++)/*输出矩阵b*/{for(j=0;j<2;j++)

printf("%3d",b[i][j]);printf("n");}}

C语言常用算法4.字符处理(1)字符统计:对字符串中

各种字符出现的次数的统计。典型例题:任意读入一个只含小

写字母的字符串,统计其中每个字母的个数。#include

"stdio.h"main(){chara[100];intn[26]={0};inti;/*定义26个计

数器并置初值0*/gets(a);for(i=0;a[i]!='0';i++)/*n[0]中存

放’a’的个数,n[1]中存放’b’的个数……*/n[a[i]-'a']++;/*各字

符的ASCII码值减去’a’的ASCII码值,正好得到对应计数器下标

*/for(i=0;i<26;i++)if(n[i]!=0)printf("%c:%dn",i+'a',n[i]);}

(2)字符加密例如、对任意一个只含有英文字母的字符串,

将每一个字母用其后的第三个字母替代后输出(字母X后的第

三个字母为A,字母Y后的第三个字母为B,字母Z后的第三

个字母为C。)#include"stdio.h"#include"string.h"main()

{chara[80]="China";inti;for(i=0;i

if(a[i]>='x'&&a[i]='X'&&a[i]<='Z')a[i]=a[i]-26+3;

elsea[i]=a[i]+3;puts(a);}5.整数各数位上数字的获取算法核

心是利用“任何正整数整除10的余数即得该数个位上的数字”的

特点,用循环从低位到高位依次取出整数的每一数位上的数字。

例1、任意读入一个5位整数,输出其符号位及从高位到低位

上的数字。main(){longx;intw,q,b,s,g;scanf("%ld",&x);

if(x<0){printf("-,");x=-x;}w=x/10000;/*求万位上的数字*/

q=x/1000%10;/*求千位上的数字*/b=x/100%10;/*求百位

上的数字*/s=x/10%10;/*求十位上的数字*/g=x%10;

/*求个位上的数字*/printf("%d,%d,%d,%d,%dn",w,q,b,s,g);}

例2、任意读入一个整数,依次输出其符号位及从低位到高位

上的数字。[分析]此题读入的整数不知道是几位数,但可以用

以下示例的方法完成此题:

C语言常用算法例如读入的整数为3796,存放在x中,执行

x%10后得余数为6并输出;将x/10得379后赋值给x。再执

行x%10后得余数为9并输出;将x/10得37后赋值给x„„直到

商x为0时终止。main(){longx;scanf("%ld",&x);if(x<0)

{printf("-");x=-x;}do/*为了能正确处理0,要用

do_while循环*/{printf("%d",x%10);

x=x/10;}while(x!=0);printf("n");}例3、任意读入一个整

数,依次输出其符号位及从高位到低位上的数字。[分析]此题

必须借助数组将依次求得的低位到高位的数字保存后,再逆序

输出。main(){longx;inta[20],i,j;scanf("%ld",&x);if(x<0)

{printf("-");x=-x;}i=0;do{a[i]=x%10;x=x/10;

i++;}while(x!=0);for(j=i-1;j>=0;j--)printf("%d",a[j]);

printf("n");}6.辗转相除法求两个正整数的最大公约数该算

法的要领是:假设两个正整数为a和b,先求出前者除以后者

的余数,存放到变量r中,若r不为0,则将b的值得赋给a,

将r的值得赋给b;再求出a除以b的余数,仍然存放到变量r

中„„如此反复,直至r为0时终止,此时b中存放的即为原来

两数的最大公约数。例1、任意读入两个正整数,求出它们的

最大公约数。[法一:用while循环时,最大公约数存放于b中]

main(){inta,b,r;doscanf("%d%d",&a,&b);

while(a<=0||b<=0);/*确保a和b为正整数*/r=a%b;

while(r!=0){a=b;b=r;r=a%b;}printf("%dn",b);}[法二:用

do…while循环时,最大公约数存放于a中]

C语言常用算法main(){inta,b,r;doscanf("%d%d",&a,&b);

while(a<=0||b<=0);/*确保a和b为正整数*/do

{r=a%b;a=b;b=r;}while(r!=0);printf("%dn",a);}【引申】

可以利用最大公约数求最小公倍数。提示:两个正整数a和b

的最小公倍数=a×b/最大公约数。例2、任意读入两个正整数,

求出它们的最小公倍数。[法一:利用最大公约数求最小公倍数]

main(){inta,b,r,x,y;doscanf("%d%d",&a,&b);

while(a<=0||b<=0);/*确保a和b为正整数*/x=a;y=b;

/*保留a、b原来的值*/r=a%b;while(r!=0){a=b;b=r;r=a%b;}

printf("%dn",x*y/b);}[法二:若其中一数的最小倍数也是另

一数的倍数,该最小倍数即为所求]main(){inta,b,r,i;do

scanf("%d%d",&a,&b);while(a<=0||b<=0);/*确保a和b为正

整数*/i=1;while(a*i%b!=0)i++;printf("%dn",i*a);}

7.求最值即求若干数据中的最大值(或最小值)。算法要领

是:首先将若干数据存放于数组中,通常假设第一个元素即为

最大值(或最小值),赋值给最终存放最大值(或最小值)的

max(或min)变量中,然后将该量max(或min)的值与数组

其余每一个元素进行比较,一旦比该量还大(或小),则将此元

素的值赋给max(或min)„„所有数如此比较完毕,即可求得

最大值(或最小值)。例1、任意读入10个数,输出其中的最

大值与最小值。#defineN10main(){inta[N],i,max,min;

for(i=0;i

for(i=1;i

C语言常用算法if(a[i]>max)max=a[i];elseif(a[i]

min=a[i];printf("max=%d,min=%dn",max,min);}8.判断素

数素数又称质数,即“只能被1和自身整除的大于1的自然数”。

判断素数的算法要领就是依据数学定义,即若该大于1的正整

数不能被2至自身减1整除,就是素数。例1、任意读入一个

正整数,判断其是否为素数。main(){intx,k;do

scanf("%d",&x);while(x<=1);/*确保读入大于1的正整数*/

for(k=2;k<=x-1;k++)if(x%k==0)break;/*一旦能被2~自身-1整

除,就不可能是素数*/if(k==x)printf("%dissushun",x);

elseprintf("%disnotsushun",x);}以上例题可以用以下两种变

形来解决(需要使用辅助判断的逻辑变量):【变形一】将“2~

自身-1”的范围缩小至“2~自身的一半”main(){intx,k,flag;

doscanf("%d",&x);while(x<=1);flag=1;/*先假设x就是素数

*/for(k=2;k<=x/2;k++)if(x%k==0){flag=0;break;}/*一旦不可

能是素数,即置flag为0*/if(flag==1)printf("%dis

sushun",x);elseprintf("%disnotsushun",x);}【变形二】将

“2~自身-1”的范围缩小至“2~自身的平方根”#include"math.h"

main(){intx,k,flag;doscanf("%d",&x);while(x<=1);flag=1;

/*先假设x就是素数*/for(k=2;k<=(int)sqrt(x);k++)

if(x%k==0){flag=0;break;}/*一旦不可能是素数,即置flag为0*/

if(flag==1)printf("%dissushun",x);elseprintf("%disnot

sushun",x);}例2、用筛选法求得100以内的所有素数。算法

为:(1)定义一维数组a,其初值为:2,3,„„,100;

(2)若a[k]不为0,则将该元素以后的所有a[k]的倍数的数组

元素置为0;(3)a中不为0的元素,均为素数。

#include

C语言常用算法#includemain(){int

k,j,a[101];clrscr();/*清屏函数*/for(k=2;k<101;k++)a[k]=k;

for(k=2;k

if(a[k]!=0&&a[j]!=0)if(a[j]%a[k]==0)a[j]=0;

for(k=2;k<101;k++)if(a[k]!=0)printf("%5d",a[k]);}9.数组元素

的插入、删除(1)数组元素的插入此算法一般是在已经有序

的数组中再插入一个数据,使数组中的数列依然有序。算法要

领是:假设待插数据为x,数组a中数据为升序序列。①先将

x与a数组当前最后一个元素进行比较,若比最后一个元素还

大,就将x放入其后一个元素中;否则进行以下步骤;②先查

找到待插位置。从数组a的第1个元素开始找到不比x小的第

一个元素,设其下标为i;③将数组a中原最后一个元素至第

i个元素依次一一后移一位,让出待插数据的位置,即下标为i

的位置;④将x存放到a(i)中。例题参见前面“‘排序’中插入法

排序的例1”。(2)数组元素的删除此算法的要领是:首先要

找到(也可能找不到)待删除元素在数组中的位置(即下标),

然后将待删元素后的每一个元素向前移动一位,最后将数组元

素的个数减1。例1、数组a中有若干不同考试分数,任意读

入一个分数,若与数组a中某一元素值相等,就将该元素删除。

#defineN6main(){intfs[N]={69,90,85,56,44,80},x;inti,j,n;

n=N;scanf("%d",&x);/*任意读入一个分数值*//*以下查找

待删分数的位置,即元素下标*/for(i=0;i

if(fs[i]==x)break;if(i==n)printf("Notfound!n");else/*将

待删位置之后的所有元素一一前移*/{for(j=i+1;j

1]=fs[j];n=n-1;/*元素个数减1*/

C语言常用算法}for(i=0;i

10.二维数组的其他典型问题(1)方阵的特点行列相等的矩

阵又称方阵。其两条对角线中“”方向的为主对角线,“/”方向

的为副对角线。主对角线上各元素的下标特点为:行列值相等;

副对角线上各元素的下标特点为:行列值之和都为阶数加1。

主对角线及其以下部分(行值大于列值)称为下三角。例1、

输出如下5阶方阵。31

223331233331#defineN5main(){int

a[N][N],i,j;for(i=0;i

a[i][j]=1;elseif(i

for(i=0;i

printf("n");}}例2、输出如下5阶方阵。12345

23456345674567856789

#defineN5main(){inta[N][N],i,j;for(i=0;i

for(j=0;j

每个元素,其值等于行列值之和+1*/

C语言常用算法for(i=0;i

printf("%3d",a[i][j]);printf("n");}}(2)杨辉三角形n0杨辉

三角形的每一行是(x+y)的展开式各项的系数。例如第一行是

(x+y),其系数为1;第二1222行是(x+y),其系数为1,1;第三

行是(x+y),其展开式为x+2xy+y,系数分别为1,2,1;„„直观

形式如下:464115

101051„„分析以上形式,可以发现其规律:是n阶方阵

的下三角,第一列和主对角线均为1,其余各元素是它的上一

行、同一列元素与上一行、前一列元素之和。例1、编程输出

杨辉三角形的前10行。#defineN10main(){inta[N][N],i,j;

for(i=0;i

1;j++)a[i][j]=a[i-1][j-1]+a[i-1][j];for(i=0;i

{for(j=0;j<=i;j++)printf("%4d",a[i][j]);printf("n");}}

例2、以等腰三角形的形状输出杨辉三角形的前5行。

1111211331

14641#defineN5main(){inta[N][N],i,j;

for(i=0;i

C语言常用算法a[i][0]=a[i][i]=1;for(i=0;i

for(j=1;j

{for(j=N-i;j>=0;j--)printf("");/*输出时每行前导空格递减*/

for(j=0;j<=i;j++)printf("%4d",a[i][j]);printf("n");}}

👁️ 阅读量:0