C语言基本算法简单级别Word文档格式.docx

上传人:b****6 文档编号:8538740 上传时间:2023-05-11 格式:DOCX 页数:20 大小:27.14KB
下载 相关 举报
C语言基本算法简单级别Word文档格式.docx_第1页
第1页 / 共20页
C语言基本算法简单级别Word文档格式.docx_第2页
第2页 / 共20页
C语言基本算法简单级别Word文档格式.docx_第3页
第3页 / 共20页
C语言基本算法简单级别Word文档格式.docx_第4页
第4页 / 共20页
C语言基本算法简单级别Word文档格式.docx_第5页
第5页 / 共20页
C语言基本算法简单级别Word文档格式.docx_第6页
第6页 / 共20页
C语言基本算法简单级别Word文档格式.docx_第7页
第7页 / 共20页
C语言基本算法简单级别Word文档格式.docx_第8页
第8页 / 共20页
C语言基本算法简单级别Word文档格式.docx_第9页
第9页 / 共20页
C语言基本算法简单级别Word文档格式.docx_第10页
第10页 / 共20页
C语言基本算法简单级别Word文档格式.docx_第11页
第11页 / 共20页
C语言基本算法简单级别Word文档格式.docx_第12页
第12页 / 共20页
C语言基本算法简单级别Word文档格式.docx_第13页
第13页 / 共20页
C语言基本算法简单级别Word文档格式.docx_第14页
第14页 / 共20页
C语言基本算法简单级别Word文档格式.docx_第15页
第15页 / 共20页
C语言基本算法简单级别Word文档格式.docx_第16页
第16页 / 共20页
C语言基本算法简单级别Word文档格式.docx_第17页
第17页 / 共20页
C语言基本算法简单级别Word文档格式.docx_第18页
第18页 / 共20页
C语言基本算法简单级别Word文档格式.docx_第19页
第19页 / 共20页
C语言基本算法简单级别Word文档格式.docx_第20页
第20页 / 共20页
亲,该文档总共20页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

C语言基本算法简单级别Word文档格式.docx

《C语言基本算法简单级别Word文档格式.docx》由会员分享,可在线阅读,更多相关《C语言基本算法简单级别Word文档格式.docx(20页珍藏版)》请在冰点文库上搜索。

C语言基本算法简单级别Word文档格式.docx

/*特殊的累加式*/

1+2+3+...+100=%d\n"

s);

【解析】程序中加粗部分为累加式的典型形式,赋值号左右都出现的变量称为累加器,其中“i=i+1”为特殊的累加式,每次累加的值为1,这样的累加器又称为计数器。

3.累乘

累乘算法的要领是形如“s=s*A”的累乘式,此式必须出现在循环中才能被反复执行,从而实现累乘功能。

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

例1、求10!

[分析]10!

=1×

……×

10

{inti;

longc;

c=1;

=10)

{c=c*i;

/*累乘式*/

1*2*3*...*10=%ld\n"

c);

二、非数值计算经典算法

1.穷举

也称为“枚举法”,即将可能出现的每一种情况一一测试,判断是否满足条件,一般采用循环来实现。

例1、用穷举法输出所有的水仙花数(即这样的三位正整数:

其每位数位上的数字的立方和与该数相等,比如:

13+53+33=153)。

[法一]

{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("

%d\n"

x);

【解析】此方法是将100到999所有的三位正整数一一考察,即将每一个三位正整数的个位数、十位数、百位数一一求出(各数位上的数字的提取算法见下面的“数字处理”),算出三者的立方和,一旦与原数相等就输出。

共考虑了900个三位正整数。

[法二]

{intg,s,b;

for(b=1;

b<

=9;

b++)

for(s=0;

s<

s++)

for(g=0;

g<

g++)

if(b*b*b+s*s*s+g*g*g==b*100+s*10+g)printf("

b*100+s*10+g);

【解析】此方法是用1到9做百位数字、0到9做十位和个位数字,将组成的三位正整数与每一组的三个数的立方和进行比较,一旦相等就输出。

共考虑了900个组合(外循环单独执行的次数为9,两个内循环单独执行的次数分别为10次,故if语句被执行的次数为9×

10×

10=900),即900个三位正整数。

与法一判断的次数一样。

2.排序

&

(1)冒泡排序(起泡排序)

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

①从存放序列的数组中的第一个元素开始到最后一个元素,依次对相邻两数进行比较,若前者大后者小,则交换两数的位置;

②第①趟结束后,最大数就存放到数组的最后一个元素里了,然后从第一个元素开始到倒数第二个元素,依次对相邻两数进行比较,若前者大后者小,则交换两数的位置;

③重复步骤①n-1趟,每趟比前一趟少比较一次,即可完成所求。

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

#definen10

{inta[n],i,j,t;

for(i=0;

i<

n;

i++)scanf("

%d"

a[i]);

for(j=1;

j<

=n-1;

j++)/*n个数处理n-1趟*/

=n-1-j;

i++)/*每趟比前一趟少比较一次*/

if(a[i]>

a[i+1]){t=a[i];

a[i]=a[i+1];

a[i+1]=t;

i++)printf("

a[i]);

(2)选择法排序

选择法排序是相对好理解的排序算法。

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

①从数组存放的n个数中找出最小数的下标(算法见下面的“求最值”),然后将最小数与第1个数交换位置;

②除第1个数以外,再从其余n-1个数中找出最小数(即n个数中的次小数)的下标,将此数与第2个数交换位置;

③重复步骤①n-1趟,即可完成所求。

例1、任意读入10个整数,将其用选择法按升序排列后输出。

/

{inta[n],i,j,k,t;

i++)scanf("

n-1;

i++)/*处理n-1趟*/

{k=i;

/*总是假设此趟处理的第一个(即全部数的第i个)数最小,k记录其下标*/

for(j=i+1;

j++)

if(a[j]<

a[k])k=j;

if(k!

=i){t=a[i];

a[i]=a[k];

a[k]=t;

}

i++)

(3)插入法排序

要想很好地掌握此算法,先请了解“有序序列的插入算法”,就是将某数据插入到一个有序序列后,该序列仍然有序。

插入算法参见下面的“数组元素的插入”。

例1、将任意读入的整数x插入一升序数列后,数列仍按升序排列。

#definen10

{inta[n]={-1,3,6,9,13,22,27,32,49},x,j,k;

/*注意留一个空间给待插数*/

x);

if(x>

a[n-2])a[n-1]=x;

/*比最后一个数还大就往最后一个元素中存放*/

else/*查找待插位置*/

{j=0;

while(j<

=n-2&

x>

a[j])j++;

/*从最后一个数开始直到待插位置上的数依次后移一位*/

for(k=n-2;

k>

=j;

k--)a[k+1]=a[k];

a[j]=x;

/*插入待插数*/}

for(j=0;

j++)printf("

%d"

a[j]);

插入法排序的要领就是每读入一个数立即插入到最终存放的数组中,每次插入都使得该数组有序。

例2、任意读入10个整数,将其用插入法按降序排列后输出。

-

{inta[n],i,j,k,x;

a[0]);

/*读入第一个数,直接存到a[0]中*/

j++)/*将第2至第10个数一一有序插入到数组a中*/

{scanf("

if(x<

a[j-1])a[j]=x;

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

else/*以下查找待插位置*/

{i=0;

while(x<

a[i]&

=j-1)i++;

/*以下for循环从原最后一个数开始直到待插位置上的数依次后移一位*/

for(k=j-1;

k>

=i;

k--)a[k+1]=a[k];

a[i]=x;

/*插入待插数*/

(4)归并排序

即将两个都升序(或降序)排列的数据序列合并成一个仍按原序排列的序列。

例1、有一个含有6个数据的升序序列和一个含有4个数据的升序序列,将二者合并成一个含有10个数据的升序序列。

@

#definem6

#definen4

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

inti,j,k,c[m+n];

i=j=k=0;

m&

j<

n)/*将a、b数组中的较小数依次存放到c数组中*/

{if(a[i]<

b[j]){c[k]=a[i];

i++;

else{c[k]=b[j];

j++;

k++;

while(i>

=m&

n)/*若a中数据全部存放完毕,将b中余下的数全部存放到c中*/

{c[k]=b[j];

while(j>

=n&

i<

m)/*若b中数据全部存放完毕,将a中余下的数全部存放到c中*/

{c[k]=a[i];

m+n;

i++)printf("

c[i]);

3.查找

(1)顺序查找(即线性查找)

顺序查找的思路是:

将待查找的量与数组中的每一个元素进行比较,若有一个元素与之相等则找到;

若没有一个元素与之相等则找不到。

例1、任意读入10个数存放到数组a中,然后读入待查找数值,存放到x中,判断a中有无与x等值的数。

.

#defineN10

{inta[N],i,x;

N;

/*以下读入待查找数值*/

i++)if(a[i]==x)break;

/*一旦找到就跳出循环*/

if(i<

N)printf("

Found!

\n"

);

elseprintf("

Notfound!

(2)折半查找(即二分法)

|

顺序查找的效率较低,当数据很多时,用二分法查找可以提高效率。

使用二分法查找的前提是数列必须有序。

二分法查找的思路是:

要查找的关键值同数组的中间一个元素比较,若相同则查找成功,结束;

否则判别关键值落在数组的哪半部分,就在这半部分中按上述方法继续比较,直到找到或数组中没有这样的元素值为止。

例1、任意读入一个整数x,在升序数组a中查找是否有与x等值的元素。

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

intx,high,low,mid;

/*x为关键值*/

high=n-1;

low=0;

mid=(high+low)/2;

while(a[mid]!

=x&

low<

high)

~

{if(x<

a[mid])high=mid-1;

/*修改区间上界*/

elselow=mid+1;

/*修改区间下界*/

mid=(high+low)/2;

if(x==a[mid])printf("

Found%d,%d\n"

x,mid);

elseprintf("

Notfound\n"

三、数值计算常用经典算法:

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的和。

{floats;

inti;

s=;

for(i=1;

=100;

i++)s=s+i;

1+1/2+1/3+...+1/100=%f\n"

【解析】程序中加粗部分就是利用项次i的倒数直接描述出每一项,并进行累加。

因为i是整数,故分子必须写成的形式!

(2)间接法求通项(即递推法)

例2、计算下列式子前20项的和:

1+1/2+2/3+3/5+5/8+8/13+……。

[分析]此题后项的分子是前项的分母,后项的分母是前项分子分母之和。

{floats,fz,fm,t,fz1;

inti;

!

s=1;

/*先将第一项的值赋给累加器s*/

fz=1;

fm=2;

t=fz/fm;

/*将待加的第二项存入t中*/

for(i=2;

=20;

{s=s+t;

/*以下求下一项的分子分母*/

fz1=fz;

/*将前项分子值保存到fz1中*/

fz=fm;

/*后项分子等于前项分母*/

fm=fz1+fm;

/*后项分母等于前项分子、分母之和*/

1+1/2+2/3+...=%f\n"

下面举一个通项的一部分用直接法描述,另一部分用递推法描述的级数计算的例子:

例3、计算级数

的值,当通项的绝对值小于eps时计算停止。

#include<

>

floatg(floatx,floateps);

{floatx,eps;

%f%f"

x,&

eps);

\n%f,%f\n"

x,g(x,eps));

floatg(floatx,floateps)

{intn=1;

floats,t;

t=1;

do{t=t*x/(2*n);

s=s+(n*n+1)*t;

/*加波浪线的部分为直接法描述部分,t为递推法描述部分*/

n++;

}while(fabs(t)>

returns;

四、其他常见算法

'

1.迭代法

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

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

例如,猴子吃桃问题。

猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个。

第二天早上又将剩下的桃子吃掉一半,又多吃了一个。

以后每天早上都吃了前一天剩下的一半零一个。

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

编程求第一天共摘多少桃子。

{intday,peach;

peach=1;

for(day=9;

day>

=1;

day--)peach=(peach+1)*2;

Thefirstday:

peach);

2.进制转换

(1)十进制数转换为其他进制数

?

一个十进制正整数m转换成r进制数的思路是,将m不断除以r取余数,直到商为0时止,以反序输出余数序列即得到结果。

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

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

voidtran(intm,intr,charstr[],int*n)

{charsb[]="

09ABCDEF"

;

inti=0,g;

do{g=m%r;

str[i]=sb[g];

m=m/r;

i++;

}while(m!

=0);

*n=i;

{intx,r0;

/*r0为进制基数*/

inti,n;

/*n中存放生成序列的元素个数*/

chara[50];

r0);

0&

r0>

=2&

r0<

=16)

{tran(x,r0,a,&

n);

for(i=n-1;

i>

=0;

i--)printf("

%c"

printf("

elseexit(0);

(2)其他进制数转换为十进制数

其他进制整数转换为十进制整数的要领是:

“按权展开”,例如,有二进制数101011,则其十进制形式为1×

25+0×

24+1×

23+0×

22+1×

21+1×

20=43。

若r进制数an……a2a1(n位数)转换成十进制数,方法是an×

rn-1+……a2×

r1+a1×

r0。

其他进制数只能以字符串形式输入。

例1、任意读入一个二至十六进制数(字符串),转换成十进制数后输出。

#include"

"

{charx[20];

intr,d;

gets(x);

/*输入一个r进制整数序列*/

r);

/*输入待处理的进制基数2-16*/

d=Tran(x,r);

%s=%d\n"

x,d);

intTran(char*p,intr)

{intd,i,cr;

charfh,c;

d=0;

fh=*p;

if(fh=='

-'

)p++;

strlen(p);

{c=*(p+i);

if(toupper(c)>

='

A'

)cr=toupper(c)-'

+10;

elsecr=c-'

0'

d=d*r+cr;

)d=-d;

return(d);

}

4.字符处理

(1)字符统计:

对字符串中各种字符出现的次数的统计。

典型例题:

任意读入一个只含小写字母的字符串,统计其中每个字母的个数。

"

{chara[100];

intn[26]={0};

/*定义26个计数器并置初值0*/

gets(a);

a[i]!

='

\0'

;

i++)/*n[0]中存放’a’的个数,n[1]中存放’b’的个数……*/

n[a[i]-'

a'

]++;

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

for(i=0;

26;

if(n[i]!

=0)printf("

%c:

%d\n"

i+'

n[i]);

(2)字符加密

例如、对任意一个只含有英文字母的字符串,将每一个字母用其后的第三个字母替代后输出(字母X后的第三个字母为A,字母Y后的第三个字母为B,字母Z后的第三个字母为C。

#include"

{chara[80]="

China"

strlen(a);

i++)

if(a[i]>

x'

a[i]<

z'

||a[i]>

X'

Z'

)a[i]=a[i]-26+3;

elsea[i]=a[i]+3;

puts(a);

5.整数各数位上数字的获取

算法核心是利用“任何正整数整除10的余数即得该数个位上的数字”的特点,用循环从低位到高位依次取出整数的每一数位上的数字。

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

{longx;

intw,q,b,s,g;

%ld"

0){printf("

-,"

x=-x;

w=x/10000;

/*求万位上的数字*/

q=x/1000%10;

/*求千位上的数字*/

:

b=x/100%10;

/*求百位上的数字*/

/*求十位上的数字*/

g=x%10;

/*求个位上的数字*/

%d,%d,%d,%d,%d\n"

w,q,b,s,g);

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

[分析]此题读入的整数不知道是几位数,但可以用以下示例的方法完成此题:

例如读入的整数为3796,存放在x中,执行x%10后得余数为6并输出;

将x/10得379后赋值给x。

再执行x%10后得余数为9并输出;

将x/10得37后赋值给x……直到商x为0时终止。

scanf("

-"

do/*为了能正确处理0,要用do_while循环*/

{printf("

x%10);

x=x/10;

}while(x!

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

[分析]此题必须借助数组将依次求得的低位到高位的数字保存后,再逆序输出。

inta[20],i,j;

i=0;

do{a[i]=x%10;

x=x/10;

i++;

}while(x!

for(j=i-1;

j>

j--)

6.辗转相除法求两个正整数的最大公约数

该算法的要领是:

假设两个正整数为a和b,先求出前者除以后者的余数,存放到变量r中,若r不为0,则将b的值得赋给a,将r的值得赋给b;

再求出a除以b的余数,仍然存放到变量r中……如此反复,直至r为0时终止,此时b中存放的即为原来两数的最大公约数。

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

[法一:

用while循环时,最大公约数存放于b中]

{inta,b,r;

doscanf("

while(a<

=0||b<

/*确保a和b为正整数*/

r=a%b;

while(r!

=0)

{

{a=b;

b=r;

r=a%b;

b);

[法二:

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

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 工作范文 > 行政公文

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2