版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
算法设计与分析
实验报告
学院信息科学与技术学院
专业班级软件工程3班
学号_______20122668__________
姓名_______王建君____________
指导教师尹治本___________
2014年10月
实验一同时求最大元与次大元
一、问题提出
在N个元素中同时求出最大元与次大元。
二、求解思路
利用分治法解决问题。将一个规模为n的问题分解为k个规模较小的子问题,这些子问
题互相独立且与原问题相同。递归地解这些子问题,然后将各个子问题解合并得到原问题的
解。
三、算法复杂度
当n=l时,不需要比较就可知最大元和次大元均为该数本身。当n=2时,一次比较就
可以找出两个元素的最大元和次大元。当n>2时,可以把n个数据元素分为大致相等的两
半,一半有n/2个数据元素,而另一半有n/2个数据元素。先分别找出各自组中的最大元和
最小元,然后将两个最大元进行比较,就可得n个元素的最大元;将两个最小元中的大元
与两个最大元中的小元进行比较,就可得n个元素的次大元。在规模为n的数据元素集合中
找出最大元和次大元,至少需要5n/2-4次比较,即5n/2-4是找最大次大元算法的下界,得
算法复杂度T(%)=5〃/2-4=O(n)o
四、源代码
#include<stdio.h>
#include<stdlib.h>
#defineN10〃宏定义元素的个数
intmax(inta,intb)
(
if(a>b)
returna;
else
returnb;
}
intmin(inta,intb)
(
if(a<b)
returna;
else
returnb;
)
voidSearch(inta[],int*max0,int*secondO,intn)
intg[30];
inti,m;
intmax1,max2,second1,second2;
if(n==l)
(
*max0=a[0];
*second0=a[0];
)
elseif(n==2)
(
*max0=max(a[0],a[1]);
*second0=min(a[0],a[1]);
)
else
(
m=n/2;
fbr(i=0;i<m;i++)
g[i]=a[i];
Search(g,&max1,&second1,m);
fbr(i=O;i<n-m;i++)
g[i]=a[i+m];
Search(g,&max2,&second2,n-m);
*maxO=max(max1,max2);
*secondO=max(min(max1,max2),max(second1,second2));
)
)
intmain()
(
inta[N];
inti,max,second;
system(ntitle软件3班王建君20122668分治法求最大元与次大元)
printf("请输入%d个数字:\n”,N);
for(i=0;i<N;i++)
scanf(H%dH,&a[i]);
Search(a,&max,&second,N);
printf("最大元为%d\n次大元为%小!1”,max,second);
return0;
)
五、结果分析
运算结果截图如下
S3软件3班王建君20122668
请输入10个数字:
12349687432342
尾木元力87
次大兀为43
Pressanykeytocontinue
依次输入10个数字12、3、4、9、6、87、34、23、4、2后求得最大元为87,次大元为34。
实验二实现两个大整数的乘法
一、问题提出
实现两个大整数的乘法。
二、求解思路
利用分治法解决问题。将一个规模为n的问题分解为k个规模较小的子问题,这些子问
题互相独立且与原问题相同。递归地解这些子问题,然后将各个子问题解合并得到原问题的
解。
三、算法复杂度
设X和Y都是n位的二进制整数,现在要计算它们的乘积XY,我们将n位的二进制整
数X和Y各分为2段,每段的长为n/2位(为简单起见,假设n是2的塞),如下图所示:
X=AB,Y=CD
n/2位勿/2位n/2位n/2位
由此,X=A2n/2+B,Y=C2n/2+D,这样,X和Y的乘积可表示为:
XY=AC2n+[(A-B)(D-C)+AC+BD]2n/2+BD。它仅需做3次n/2位整数的乘法(AC,BD和
(A-B)(D-C)),6次加、减法和2次移位,由此可得算法复杂度为:
,、。n=1
T(n)=
3T(n/2)+cnn>1
用解递归方程的套用法可得其解为:T(n)=。(〃l°g23)=O(“'9)。
四、源代码
#include<iostream>
#include<sstream>
#include<string>
#include<stdlib.h>
usingnamespacestd;
//string类型转换成int类型
intstring_to_num(stringk)
(
intback;
stringstreaminstr(k);
instr»back;
returnback;
)
//整形数转换为string类型
stringnum_to_string(intintValue)
(
stringresult;
stringstreamstream;
stream«intValue;
stream»result;
returnresult;
)
〃在字符串str前添加s个零
stringstringBeforeZero(stringstr,ints)
(
for(inti=O;i<s;i++)
(
str.insert(O,"On);
)
returnstr;
}
//两个大整数字符串相加,超出计算机表示范围的数也能实现相加(本函数可以实现大整数
加法运算)
stringstringAddstring(stringstri,stringstr2)
(
〃假定strl和str2是相等的长度,不相等时在前面自动补零,使两个字符串长度相等
if(strl.size()>str2.size())
(
str2=stringBeforeZero(str2,str1.size()-str2.size());
)
elseif(strl.size()<str2.size())
(
strl=stringBeforeZero(str1,str2.size()-strl.size());
)
stringresult;
intflag=O;〃前一进位是否有标志,0代表无进位,1代表有进位
for(inti=strl,size()-l;i>=0;i—)
(
intc=(strl[i]-'0')+(str2[i]-'0')+flag;//利用ASCII码对字符进行运算,这里加上flag
代表的是:当前一位有进位时加1,无进位时加0
flag=c/10;〃c大于10时,flag置为1,否则为0
c%=10;//c大于10时取模,否则为其本身
result.insert(0,num_to_string(c));〃在result字符串最前端插入新生成的单个字符
)
if(0!=flag)〃最后一为(最高位)判断,如果有进位则再添一位
(
result.insert(0,num_to_string(flag));
)
returnresult;
)
/*两个大整数字符串相减,超出计算机表示范围的数也能实现相减(在这里比较特殊,第一
个参数一定大于第二个参数,
因为:al*b0+a0*bl=(al+a0)*(bl+b0)-(al*bl+a0*b0)>0,所以(al+a0)*(bl+b0)>
(al*bl+a0*b0)
这个函数的两个参数,第一个代表的其实就是(al+a0)*(bl+b0),第二个代表的其实就是
(al*bl+a0*b0)
所以本函数里不用考虑最终得到结果为负数的情况,至于计算有关大整数负数相乘的问题可
以通过其他途径判断
*/
stringstringSubtractstring(stringstri,stringstr2)
(
〃对传进来的两个数进行修剪,如果前面几位有0则先去掉,便于统一处理
while('O'==strl[O]&&strl.size()>l)
(
strl=strl.substr(l,strl.size()-l);
)
while(O==str2[0]&&str2.size()>l)
(
str2=str2.substr(l,str2.size()-l);
)
〃使两个字符串长度相等
if(strl.size()>str2.size())
(
str2=stringBeforeZero(str2,str1.size()-str2.size());
)
stringresult;
for(inti=strl.size()-l;i>=O;i—)
(
intc=(strl[i]-'0')-(str2[i]-O);〃利用ASCII码进行各位减法运算
if(c<0)〃当不够减时向前一位借位,前一位也不够位时再向前一位借位,依次如下
c+=10;
intprePos=i-1;
charpreChar=str1[prePos];
while('O'==preChar)
(
strl[prePos]=,9,;
prePos-=1;
preChar=strl[prePos];
)
strl[prePos]-=1;
)
result.insert(0,num_to_string(c));〃在result字符串最前端插入新生成的单个字符
)
returnresult;
)
〃在字符串str后跟随s个零
stringstringFollowZero(strings)
(
for(inti=0;i<s;i++)
{
str.insert(str.size(),"O");
)
returnstr;
)
〃分治法大整数乘法实现函数
stringIntMult(stringx,stringy)〃递归函数
(
//对传进来的第一个数进行修剪,如果前面几位有0则先去掉,便于统一处理
while('O'==x[0]&&x.size()>1)
{
x=x.substr(1,x.size()-1);
)
//对传进来的第二个数进行修剪,如果前面几位有0则先去掉,便于统一处理
while(O==y[0]&&y.size()>l)
{
y=y.substr(1,y.size()-1);
)
/*这里的f变量代表在两个数据字符串长度不想等或者不是2的指数倍的情况下,所要统一
的长度,这样做是为了让数据长度为2的n次方
的情况下便于利用分治法处理
*/
intf=4;
/*当两字符串中有任意一个字符串长度大于2时都要通过与上面定义的f值进行比较,使其
达到数据长度为2的n次方,实现方式是在前面
补0,这样可以保证数据值大小不变
*/
if(x.size()>2||y.size()>2)
if(x.sizeQ>=y.size。)//第一个数长度大于等于第二个数长度的情况
while(x.size()>f)〃判断f值
(
f*=2;
)
if(x.size()!=f)
(
x=stringBeforeZero(x,f-x.size());
y=stringBeforeZero(y,f-y.size());
)
)
else//第二个数长度大于第一个数长度的情况
(
while(y.size()>f)〃判断f值
(
f*=2;
)
if(y.size()!=f)
x=stringBeforeZero(x,f-x.size());
y=stringBeforeZero(y,f-y.size());
if(l==x.size。)//数据长度为1时,在前面补一个0(这里之所以会出现长度为1的数据
是因为前面对数据修剪过)
x=stringBeforeZero(x,1);
)
if(l==y.size())//数据长度为1时,在前面补一个0(这里之所以会出现长度为1的数据
是因为前面对数据修剪过)
y=stringBeforeZero(y,l);
}
if(x.sizeQ>y.size。)//最后一次对数据校正,确保两个数据长度统一
y=stringBeforeZero(y,x.size()-y.size());
)
if(x.size()<y.size。)//最后一次对数据校正,确保两个数据长度统一
x=stringBeforeZero(x,y.size()-x.size());
)
ints=x.size();
stringal,aO,bl,bO;
if(s>1)
al=x.substr(0,s/2);
aO=x.substr(s/2,s-l);
bl=y.substr(0,s/2);
bO=y.substr(s/2,s-l);
)
stringresult;
if(s==2)//长度为2时代表着递归的结束条件
intna=string_to_num(a1);
intnb=string_to_num(aO);
intnc=string_to_num(b1);
intnd=string_to_num(bO);
result=num_to_string((na*10+nb)*(nc*10+nd));
}
else{〃长度不为2时利用分治法进行递归运算
小提示:
c=a*b=c2*(10An)+cl*(10A(n/2))+cO;
a=alaO=al*(10A(n/2))+aO;
b=blbO=bl*(10A(n/2))+bO;
c2=al*bl;cO=aO*bO;
cl=(al+aO)*(bl+b0)-(c2+cO);
stringc2=IntMult(al,bl);//(al*bl)
stringcO=IntMult(aO,bO);//(aO*bO)
stringcl_l=stringAddstring(al,aO);//(al+aO)
stringcl_2=stringAddstring(bl,bO);//(bl+bO)
stringcl_3=IntMult(c1_1,c1_2);//(al+aO)*(bl+bO)
stringcl_4=stringAddstring(c2,c0);//(c2+cO)
stringc1=stringSubtractstring(c1_3,c1_4);//(al+aO)*(bl+b0)-(c2+cO)
strings1=stringFollowZero(c1,s/2);//cl*(10A(n/2))
strings2=stringFollowZero(c2,s);//c2*(10An)
result=stringAddstring(stringAddstring(s2,s1),cO);//c2*(10An)+cl*(10A(n/2))+cO
)
returnresult;
)
intmain()
(
intf=l;
stringA,B,C,D;
stringnuml,num2;
stringr;
system(ntitle软件3班王建君20122668分治法实现大整数乘法)
cout<<”请输入第一个大整数(任意长度):";
cin»numl;
inti=0;
〃判断第一个输入的数据是否合法,当字符串中包含非数字字符时提示用户重
新输入
for(i=0;i<numl.size();i++)
(
if(numl[i]<'0'||numl[i]>'9')
(
cout<<"您输入的数据不合法,请输入有效的整数!”<<endl;
cin»numl;
i=-l;
)
)
cout<<"请输入第二个大整数(任意长度):“;
cin»num2;
〃判断第二个输入的数据是否合法,当字符串中包含非数字字符时提示用户重
新输入
for(i=0;i<num2.size();i++)
(
if(num2[i]<'0'||num2[i]>,9,)
(
cout<〈"
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 旅馆业火灾原因分析及防范对策研究
- 科技校本课程的实践探索与思考
- DB3212-T 2085-2024 机插稻-设施番茄轮作栽培技术规程
- 部编版语文七年级上册第一单元写作 热爱写作学会观察 任务型公开课一等奖创新教学设计
- 《医用电子仪器生产过程检验检测应用指南 病人监护仪原材料进货检验》(征求意见稿)
- 家居改造工程合同范本
- 园林绿化砂石运输服务协议
- 酒水节庆活动运输协议
- 家具配送运输承包合同样本
- 儿童教育居间合作协议范本
- 谷子主要病虫害防治技术
- 乌合之众课件
- 原辅料进货记录表模板
- 《血沉临床意义》课件
- 小学数学三年级上册第七单元《长方形和正方形》单元集体备课全部教学设计
- 《公顷和平方千米的认识》教学设计教案及反思
- 《重阳节英文版》课件
- 惠州市高2024届高三第二次调研考试英语试卷(含答案)
- 海南省2023年中考数学试卷(含答案)
- 危险化学品货物运输公司管理制度汇编
- 陕西各市(精确到县区)地图PPT课件(可编辑版)
评论
0/150
提交评论