C++常用算法归纳Word格式文档下载.docx
《C++常用算法归纳Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《C++常用算法归纳Word格式文档下载.docx(21页珍藏版)》请在冰豆网上搜索。
例.求10!
。
【分析:
10!
=1×
2×
3……×
10,累乘器在进入循环前必须获得合适初值;
通常为1。
累乘式格式“C=C*……”必须出现在循环中。
注意,不要让累乘器溢出。
#include <
iostream>
usingnamespacestd;
voidmain()
{longC;
inti;
C=1;
i=1;
while(i<
=10)
{C=C*i;
i++;
}
cout<
C<<endl;
【思考:
能否将本程序稍做修改,分别输出1!
~10!
二、非数值计算常用经典算法
1、穷举法
对所有的可能性进行判断,凡是符合条件的做相应处理(输出、保存等)。
例:
输出所有的“水仙花”数,即这样的三位正整数:
其每一数位上的数字的立方之和等于该数本身。
比如,153=13+53+33。
【法一:
一重循环,难点:
求出每位数字】
#include<iostream>
usingnamespacestd;
voidmain()
{int sxh;
int b,s,g;
for(sxh=100;
sxh<
=999;
sxh++)
{b=sxh/100;
s=sxh/10%10;
g=sxh%10;
if(b*b*b+s*s*s+g*g*g==sxh)
cout<
sxh<
endl;
}
【结论:
任意一个正整数的个位数字,都可以用“该数%10”求得!
【法二:
三重循环】
#include<
iostream>
usingnamespacestd;
void main()
{intb,s,g;
for(b=1;
=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)
cout<
b*100+s*10+g<
endl;
【发现:
核心语句if被执行了900次】
2、正整数的各数位上数字的获取
例1:
任意读入一个正整数,依次输出其低位到高位上的每一位数字。
例2:
任意读入一个整数,依次输出其低位到高位上的每一位数字及其符号位,但若是0不输出符号位。
3、迭代法
例1.猴子吃桃问题。
某猴子某天摘了若干只桃子,吃了一半,不过瘾,又多吃一只;
第二天又吃了一半,不过瘾,再多吃一只……到第十天,发现只剩1只桃子了。
问第一天共摘了多少只桃子。
#include<
iostream>
usingnamespacestd;
voidmain()
{intpeach,day;
peach=1;
for(day=9;
day>
=1;
day--)
peach=(peach+1)*2;
cout<
第一天的桃子数:
peach;
【归纳:
类似于本题peach变量的特点:
其值不停地被新值替代(自身的原值变化而来),直到满足所求终止。
【问题:
能否将上述程序稍作修改,输出每一天的桃子数。
#include<iostream>
usingnamespacestd;
voidmain()
{intpeach,day;
peach=1;
for(day=9;
day>
=1;
day--)
{peach=(peach+1)*2;
第"
day<
天的桃子数:
<<peach<
<endl;
4、排序
(1)冒泡排序法(起泡法)
【算法要领:
n个数据最多处理n-1趟,每一趟从头到尾(或从尾到头)两两相邻的元素进行比较,升序排序时,若前者大后者小,则交换两数……,每一趟比前一趟少比较一次。
任意读入10个整数,升序排列后输出。
#include<
iostream>
usingnamespacestd;
voidmain()
{constintN=10;
inta[N],i,j;
for(i=0;
i<
N;
i++)
cin>
a[i];
//外循环处理N-1趟,控制趟数
for(j=1;
j<=N-1;
j++)
for(i=0;
=N-1-j;
i++)
//内循环控制每趟比较次数
if(a[i]>
a[i+1])
{intt;
t=a[i];
a[i]=a[i+1];
a[i+1]=t;
for(i=0;
i<N;
i++)
cout<<a[i]<
';
(2)选择法排序
选择法排序是相对好理解的排序算法。
假设要对含有n个数的序列进行升序排列,算法步骤是:
①从数组存放的n个数中找出最小数的下标(算法见下面的“求最值”),然后将最小数与第1个数交换位置;
②除第1个数以外,再从其余n-1个数中找出最小数(即n个数中的次小数)的下标,将此数与第2个数交换位置;
③重复步骤①n-1趟,即可完成所求。
任意读入10个数,然后进行升序排列。
【主函数—读入、调用、输出;
子函数—排序。
#include<iostream>
usingnamespacestd;
voidPX(int*p,int n) //【法1:
选择法】
{inti,j,k,t;
for(i=0;
=n-2;
i++)
{k=i;
for(j=i+1;
j<
=n-1;
j++)
if(*(p+j)<*(p+k))ﻩk=j;
if(k!
=i)
{t=*(p+i);
*(p+i)=*(p+k);
*(p+k)=t;
}
void main()
{inta[10],i;
for(i=0;
10;
i++)
cin>
a[i];
PX(a,10);
//为增大子函数灵活性,将元素个数传过去
for(i=0;
i<10;
i++)
ﻩcout<<
a[i]<
<endl;
//【法2:
以下冒泡法】
#include<
iostream>
#include<
iomanip>
usingnamespacestd;
voidPX(int*p,int n)
{inti,j;
intt;
for(j=1;
=n-1;
j++)
for(i=0;
=n-1-j;
if(*(p+i)>
*(p+i+1))
{t=*(p+i);
*(p+i)=*(p+i+1);
*(p+i+1)=t;
voidmain()
{inta[10],i;
for(i=0;
10;
i++)
>a[i];
PX(a,10);
for(i=0;
i<
10;
cout<<
setw(4)<
a[i];
5、查找:
顺序查找(线性查找)
任意读入10个数,查找其中有无9这个数。
#include<iostream>
using namespacestd;
voidmain()
{const int N=10;
int a[N],i;
N;
ﻩcin>
for(i=0;
N;
i++)//正常出口出来,i为N
if(a[i]==9)break;
if(i<
N)
cout<
<"
有"
<<
endl;
else
cout<
<"无"
endl;
【小技巧:
定义一个逻辑量】
#include<
iostream>
usingnamespacestd;
voidmain()
{const intN=10;
inta[N],i;
boolflag=false;
//先假设无
>a[i];
for(i=0;
i++)//正常出口出来,i为N
if(a[i]==9){flag=true;
break;
if(flag!
=false)
cout<
else
cout<
无"
endl;
【用while改写】
#include <iostream>
usingnamespacestd;
void main()
{constintN=10;
inta[N],i;
for(i=0;
N;
i++)cin>
a[i];
i=0;
while(i<
=N-1&
&
a[i]!
=9)i++;
if(i<
=N-1)
cout<<
endl;
cout<
"无"
endl;
6、判断素数(质数)
数学定义:
“凡是只能被1和自身整除的大于1的整数,就称为质数,即素数。
”
【换句话,即“不能被‘2~自身-1’整除”】
例1.任意读入一个大于1的整数,判断其是否为素数。
【法一:
紧扣数学定义】
iostream>
usingnamespacestd;
voidmain()
{intx;
do
{cout<
x>
1:
\n"
;
cin>
x;
}while(x<
=1);
intk;
for(k=2;
k<
=x-1;
k++)//穷举的思维
if(x%k==0)break;
if(x==k)//判断难点
cout<
x<
是素数\n"
cout<<
"不是素数\n"
【用一个小技巧:
借助一个“逻辑型”变量:
“是素数时为true,否则为false”】
#include<
usingnamespace std;
voidmain()
{cout<
x>
\n"
cin>
x;
}while(x<
boolflag;
flag=true;
//首先假设x是素数!
for(k=2;
=x-1;
k++) //穷举的思维
if(x%k==0)
{flag=false;
ﻩbreak;
if(flag==true)
cout<
else
cout<
x<
不是素数\n";
#include <
usingnamespacestd;
voidmain()
{int x,k;
cin>>
k=2;
while(x%k!
=0)k++;
if(k==x)
cout<
x<<"
是素数\n"
;
else
cout<
"不是素数\n"
【变形一:
用sqrt函数,求平方根】
#include<
iostream>
cmath>
usingnamespacestd;
{int x,k;
cin>
>x;
boolflag=true;
for(k=2;
k<=sqrt(x);
k++)
if(x%k==0){flag=false;
break;
if(flag==true)
cout<
else
cout<
x<<
不是素数\n";
7、插入、删除
三、数值计算经典算法:
1、辗转相除法求两正整数的最大公约数
任意读入2个正整数,输出其最大公约数。
#include <
iostream>
usingnamespace std;
voidmain()
{intx,y,r;
do
输入x>
0、y>
0:
cin>
y;
}while(!
(x>
0&
&y>
0));
r=x%y;
while(r!
=0)
{x=y;
y=r;
r=x%y;
cout<<
y<
【改写:
用do……while】
#include<
iostream>
usingnamespacestd;
voidmain()
{intx,y,r;
do
{cout<
输入x>0、y>
cin>
x>>y;
}while(!
0&
0));
{r=x%y;
x=y;
y=r;
}while(r!
=0);
2.级数计算(展开式的求解)
例1、求1+1/2!
+1/3!
+…+1/n!
+…,直到某项的值小于10-6为止。
直接法(略)】
【法二:
间接法(递推法)前项/项次=后项】
#include <
iostream>
usingnamespacestd;
{floats,t;
inti;
//表示项次
s=0;
t=1;
i=1;
while(t>=1e-6)
{s=s+t;
i++;
t=t/i;
cout<
<s<
endl;
例2、读入0<x<
1,计算x+x2+x3+…xn+…直到某项的值小于10-6为止。
直接法:
直接利用项次描述通项。
#include <
iostream>
#include<cmath>
using namespacestd;
voidmain()
{float x,s,t;
int i;
//能用整数,不用实数
{cout<
0<
1\n"
x;
}while(x>
=1||x<=0);
i=1;
s=0.0;
t=x;
while(t>
=1e-6)
{s=s+t;
i++;
t=pow(x,i);
<s<<
3、间接法求通项
例1、读入0<
x<1,计算x+x2+x3+…xn+…直到某项的值小于10-6为止。
递推法(间接法)求通项:
利用前项求后项。
本题中若前一项值为t,则后一项的值为t*x】
#include<
iostream>
using namespacestd;
voidmain()
{float x,s;
do
{cout<
0<x<
1\n";
cin>
}while(x>
=1||x<=0);
float t;
//用t表示通项
s=0.0;
t=x;
while(t>
=1e-6)
{s=s+t;
t=t*x;
cout<
例2、求斐比利斯数列的前20项。
1、1、2、3、5、8、13……(制定前两项,第三项开始总是前两项之和。
)
本题只能有间接法(递推法),利用前2项求后1项。
iostream>
usingnamespace std;
voidmain()
{intf1,f2,f3;
f1=f2=1;
f1<
""
f2<<
"
int i;
for(i=3;
=20;
{f3=f1+f2;
f1=f2;
f2=f3;
cout<<f3<
例3、编程输出形如上图的等腰三角形(行数灵活读入)。
*
***
*****
*******
#include<
iostream>
usingnamespacestd;
voidmain()
{int h;
读入行数>
=1"<
cin>
>h;
inti=1,j;
//用二重循环完成(循环的嵌套)
while(i<
=h)//外循环控制行数
{for(j=1;
=h-i;
j++)//第一个循环输出每行的空格
''
for(j=1;
=2*i-1;
j++) //第二个循环输出每行的星号
cout<
<'
*'
<endl;
i++;
4、矩阵转置
矩阵转置的算法要领是:
将一个m行n列矩阵(即m×
n矩阵)的每一行转置成另一个n×
m矩阵的相应列。
例、将以下2×
3矩阵转置后输出。
即将 1 23 转置成14
4 5 6 25
3 6
#include<
iostream>
#include <
iomanip>
usingnamespacestd;
{inta[2][3],b[3][2],i,j,k=1;
for(i=0;
i<2;
ﻩfor(j=0;
3;
j++)
ﻩa[i][j]=k++;
//将a转置到b中,穷举
for(i=0;
2;
i++)//以a为基准
ﻩfor(j=0;
ﻩb[j][i]=a[i][j];
for(i=0;
{for(j=0;
setw(3)<<b[i][j];
cout<
endl;
5、杨辉三角形
杨辉三角形的每一行是(x+y)n的展开式各项的系数。
例如第一行是(x+y)0,其系数为1;
第二行是(x+y)1,其系数为1,1;
第三行是(x+y)2,其展开式为x2+2xy+y2,系数分别为1,2,1;
……直观形式如下:
1
1 1
1 21
1 3 3 1
14 64 1
1 51010 5 1
……
分析以上形式,可以发现其规律:
是n阶方阵的下三角,第一列和主对角线均为1,其余各元素是它的上一行、同一列元素与上一行、前一列元素之和。
例、编程输出杨辉三角形的前10行。
iostream>
#include<
iomanip>
usingnamespace std;
{constintN=10;
inta[N][N],i,j;
//给主对角线、第一列元素赋值
for(i=0;
i++)
a[i][i]=a[i][0]=1;
//以下双循环完成其他元素赋值
for(i=2;
=N-1;
for(j=1;
j<
=i-1;
a[i][j]=a[i-1][j-1]+a[i-1][j];
for(i=0;
{for(j=0;
=i;
cout<
setw(4)<<
a[i][j];
cout<
6、求最值(最大、最小)
例、任意读入10个整数,输出其中的最大值。
iostream>
using namespacestd;
voidmain()
{constintN=10;
int a[N],i;
int max;
for(i=0;
i++)cin>
>a[i];
max=a[0];
//假设第一个获最后一个最大
for(i=1;
i++)//其余不服气
ﻩif(a[i]>
max)max=a[i];
MAX="<
<max<
<endl;