算法设计与分析复习题Word文档下载推荐.docx
- 文档编号:19730764
- 上传时间:2023-01-09
- 格式:DOCX
- 页数:41
- 大小:1.39MB
算法设计与分析复习题Word文档下载推荐.docx
《算法设计与分析复习题Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《算法设计与分析复习题Word文档下载推荐.docx(41页珍藏版)》请在冰豆网上搜索。
for(inti=0;
i<
n;
++i)
while(data[i]>
=p)
p*=10;
++d;
}
returnd;
}
voidradixsort(intdata[],intn)//基数排序
intd=maxbit(data,n);
int*tmp=newint[n];
int*count=newint[10];
//计数器
inti,j,k;
intradix=1;
for(i=1;
i<
=d;
i++)//进行d次排序
for(j=0;
j<
10;
j++)
count[j]=0;
//每次分配前清空计数器
j++)
k=(data[j]/radix)%10;
//统计每个桶中的记录数
count[k]++;
for(j=1;
count[j]=count[j-1]+count[j];
//将tmp中的位置依次分配给每个桶
for(j=n-1;
j>
=0;
j--)//将所有桶中记录依次收集到tmp中
tmp[count[k]-1]=data[j];
count[k]--;
j++)//将临时数组的内容复制到data中
data[j]=tmp[j];
radix=radix*10;
delete[]tmp;
delete[]count;
13编写一个算法,可以检测一个字符串是否回文(如:
afaddafa,abwba等)。
14如果是检测一个字符串中是否包含一个回文子串,应如何编写算法。
如果是找最大的回文子串呢?
15设n个不同的整数排好序后存在数组T[1:
n]中。
若存在一个下标i,使得T[i]=i,设计一个有效的算法找到该下标。
要求时间复杂性是O(logn)。
16编写一个采用KMP的算法查找T的子串P,并判断匹配失败的字符是否在P中,以此确定可滑动的最大距离。
17编写一个算法找出2个正文中的最长公共子序列,若要找出3个正文中的最长公共子序列,应如何编写算法。
18编写一个求解8后问题的算法,并作出时间复杂性分析。
19试分析回溯法与分支定界法的异同之处。
20采用分支定界法编写一个求解货郎担问题的算法,并作出算法时间复杂性分析。
21假设有k种不同面值的硬币(以元为单位,每种的个数不限)。
编写一个用最少的硬币数找出n元钱的算法,并分析算法的时间复杂性。
#include<
iostream.h>
intmain()
{intchange;
cout<
<
"
请输入要找给顾客的零钱(以分为单位)"
;
cin>
change;
找给顾客的五角硬币个数为:
change/50<
endl;
change=change%50;
找给顾客的壹角硬币个数为:
change/10<
change=change%10;
找给顾客的伍分硬币个数为:
change/5<
change=change%5;
找给顾客的贰分硬币个数为:
change/2<
change=change%2;
找给顾客的壹分硬币个数为:
change<
return0;
22考虑一个“模糊”的算法查找T的子串P,先快速找到与P相似的子串,再进一步确认之。
23设计一个算法确定K个矩阵相乘的最优次序,并分析该算法的时间复杂性。
方法一:
动态规划算法的基本思想是将待求解问题分成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。
与分治法不同的是,动态规划法经分解得到的子问题往往不是相互独立的,前一子问题的解为后一子问题的解提供有用的信息,可以用一个表来记录所有已解决的子问题的答案,不管该子问题以后是否被用到,只要它被计算过,就将其结果填入表中。
本实验的算法思路是:
1、计算最优值算法MatrixChain():
建立两张表(即程序中的**m和**s,利用二维指针存放),一张表存储矩阵相乘的最小运算量,主对角线上的值为0,依次求2个矩阵、3个矩阵…、直到n个矩阵相乘的最小运算量,其中每次矩阵相乘的最小运算量都在上一次矩阵相乘的最小运算量的基础上求得,最后一次求得的值即为n个矩阵相乘的最小运算量;
另一张表存储最优断开位置。
2、输出矩阵结合方式算法Traceback():
矩阵结合即是给矩阵加括号,打印出矩阵结合方式,由递归过程Traceback()完成。
分三种情况:
(1)只有一个矩阵,则只需打印出A1;
(2)有两个矩阵,则需打印出(A1A2);
(3)对于矩阵数目大于2,则应该调用递归过程Traceback()两次,构造出最优加括号方式。
三、实验源程序
建立一个矩阵的类Matrix。
Matrix.h代码
#ifndefMATRIX_H
#defineMATRIX_H
classMatrix
{
public:
Matrix();
//构造函数
~Matrix();
//析构函数
boolRun();
//运行接口函数
private:
intW;
//记录矩阵的个数
int**m;
//存放最优值,即最小运算量
int**s;
//断开位置
int*p;
//存放
boolInput();
//处理输入
boolMatrixChain();
//计算最优值算法
voidTraceback(inti,intj,int**s);
//输出矩阵加括号的方式
};
#endif
Matrix.cpp代码
#defineN50
#include<
stdlib.h>
#include"
Matrix.h"
//构造函数,作变量初始化工作,为指针分配内存空间
Matrix:
:
Matrix()
W=0;
m=newint*[N];
s=newint*[N];
for(inti=0;
N;
i++)
m[i]=newint[N];
s[i]=newint[N];
}
p=newint[N];
//析构函数,释放内存
~Matrix()
delete[]m[i];
delete[]s[i];
delete[]m;
delete[]s;
delete[]p;
//处理键盘输入
boolMatrix:
Input()
intw;
cout<
矩阵个数:
cin>
w;
W=w;
输入矩阵A1维数"
:
p[0]>
p[1];
for(inti=2;
=W;
intm=p[i-1];
输入矩阵A"
i<
维数:
p[i-1]>
p[i];
if(p[i-1]!
=m)
endl<
维数不对,矩阵不可乘!
exit
(1);
//cout<
if(p!
=NULL)
returntrue;
else
returnfalse;
//计算最优值算法
MatrixChain()
if(NULL==p)
for(inti=1;
=W;
i++)
m[i][i]=0;
for(intr=2;
r<
r++)
=W-r+1;
intj=i+r-1;
m[i][j]=m[i+1][j]+p[i-1]*p[i]*p[j];
s[i][j]=i;
for(intk=i+1;
k<
j;
k++)
intt=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];
if(t<
m[i][j])
m[i][j]=t;
s[i][j]=k;
//输出矩阵结合方式,加括号
voidMatrix:
Traceback(inti,intj,int**s)
if(i==j)
A"
i;
elseif(i+1==j)
(A"
j<
)"
("
Traceback(i,s[i][j],s);
Traceback(s[i][j]+1,j,s);
Run()
if(Matrix:
Input())
MatrixChain())
Traceback(1,W,s);
else
main.cpp代码
#include"
voidmain()
Matrixm;
m.Run();
方法二:
24设计一个算法从数A[1:
n]中同时找出最大元素和最小元素,只需要不超过1.5n-2次比较。
算法分析
求最大元和最小元,最大元和次大元的算法比较多,运用分治算法解决此问题,是因为这种方法的优越行,下面通过时间复杂度的比较来说明。
通常算法,设置一个变量,等于需要比较的数组的第一个元素,然后依次与后面的n-1经行比较,需要比较n-1次得到最大元。
同理,求得最小元的比较次数仍然是n-1次。
设
表示比较的次数则对于这种算法得到
的值为
分治算法求最大元比较
解方程结果为
虽然二者都是线性增长的,可是增长率要小一些。
实际编程时的实现有细微差距。
另外,求最大元,次大元的时候次大元总是在最大元的淘汰数组中,所以求次大元时,多了从最大元数组中找次大元的情形,n取对数,增长率仍然是比较小的。
最大最小元代码
stdio.h"
structpoint
intmax;
//thelargerone
intmin;
//thesmallerone
intarray[50];
intMax(inti,intj)
{
if(i>
=j)
returni;
returnj;
intMin(inti,intj)
structpointfun1(intoffset,intend,intn)//传入参数为查找下限,上限,注意上限下标不在查找范围内
structpointtemp,temp1,temp2;
if(n==2)
temp.max=Max(array[offset],array[end-1]);
temp.min=Min(array[offset],array[end-1]);
returntemp;
temp1=fun1(offset,(offset+end)/2,n/2);
//每次规模减半
temp2=fun1((offset+end)/2,end,n/2);
temp.max=Max(temp1.max,temp2.max);
temp.min=Min(temp1.min,temp2.min);
voidmain()
structpointa1,a2;
inti,n;
for(i=0;
50;
i++)array[i]=0;
printf("
Inputthetotaln=:
\n"
);
scanf("
%d"
&
n);
Inputthenumbers:
n;
scanf("
array[i]);
a1=fun1(0,n,n);
Max=%d\nMin=%d\n"
a1.max,a1.min);
25用分治法一个算法从数A[1:
n]中同时找出最大元素,分析算法的时间复杂性,并思考为什么是这样的结果。
同上
26在一个数组中出现次数最多的元素称为“众数”,编写一个找出众数的算法,并分析算法时间复杂性。
intmost(inta[],intlength)//length数组长度
inti,j,k;
intmax,value;
intnum[100][100];
num[0][0]=a[0];
num[0][1]=1;
j=0;
for(i=1;
length;
for(k=0;
if(a[i]==num[k][0])
num[k][1]++;
break;
if(k>
j)
j++;
num[j][0]=a[i];
num[j][1]=1;
max=0;
for(k=;
if(num[k][1]>
max)
max=num[k][1];
value=num[k][0];
returnvalue;
//出现次数最多的数字
27设计一个使用Hash法的算法在数组中找出“众数”,并分析时间复杂性。
#include<
iostream>
#include<
cstdio>
#defineN100010
usingnamespacestd;
inta[N];
intmain()
inttest;
test);
while(test--)
intn;
inti,t;
N;
i++)a[i]=0;
t);
a[t]++;
intp,ans=0;
if(a[i]>
ans)
p=i;
ans=a[i];
%d%d\n"
p,ans);
return0;
28设计一个时间复杂性不超过O(n2)的算法,找出n个数组成的序列中最长的单调递增序列。
【设计原理】
将数组a复制到数组x,先用排序算法将数组x排序,在调用查找最长公共子序列的算法求出数组a和数组x中的最长公共子序列,因为数组x是单调递增的,所以由此求出来的最长公共子序列就是题设所求的最长单调递增子序列。
【概要设计】
数据:
N:
数组元素个数。
a[N]:
用于存放数组。
X[N]:
复制数组a[N],并排序。
c[i][j]:
存储a和x的最长公共子序列的长度。
b[i][j]:
记录c[i][j]的值是由哪一个资问题的解得到的。
函数:
intPartition(inta[],intp,intt,intx);
//数组划分,将小于等于x的元素移到x左边,大于x的元素移到x右边。
voidSwap(int&
x,int&
y);
//交换元素x和y
voidQuickSort(inta[],intp,intr);
//快速排序。
voidLCSL(intm,intn,int*x,int*y,int**c,int**b);
//计算最长公共子序列长度。
voidLCS(inti,intj,int*x,int**b);
根据b[i][j]的内容打印a,x数组的最长公共子序列。
【详细设计】
ctime>
usingnamespacestd;
#defineN10
//根据b[i][j]的内容打印a,x数组的最长公共子序列。
intPartition(inta[],intp,intt);
//交换元素x和y。
//计算最长公共子序列长度
voidLCSL(intm,intn,int*x,int*y,intc[][N],intb[][N])
c[0][0]=0;
inti,j;
=m;
c[i][0]=0;
=n;
c[0][i]=0;
for(i=1;
for(j=1;
j++)
if(x[i]==y[j])
c[i][j]=c[i-1][j-1]+1;
b[i][j]=1;
elseif(c[i-1][j]>
=c[i][j-1])
c[i][j]=c[i-1][j];
b[i][j]=2;
c[i][j]=c[i][j-1];
b[i][j]=3;
c[m][m]<
//根据b[i][j]的内容打印a,x数组的最长公共子序列
voidLCS(inti,intj,int*x,intb[][N])
if(i==0||j==0)return;
if(b[i][j]==1)
LCS(i-1,j-1,x,b);
for(inty=1;
y<
y++)
if(x[y]==x[i])
return;
x[i]<
"
elseif(b[i][j]==2)
LCS(i-1,j,x,b);
else
LCS(i,j-1,x,b);
voidQuickSort(inta[],intp,intr)
if(p<
r)
intq=Partition(a,p,r);
QuickSort(a,p,q-1);
//对左半段排序
QuickSort(a,q+1,r);
//对右半段排序
intPartition(inta[],intp,intr)
inti=p,
j=r+1;
intx=a[p];
//将<
x的元素交换到左边区域
//
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 算法 设计 分析 复习题