分治法解决合并排序问题及动态规划解决矩阵连乘和最长公共子序列问题及贪心法解决哈夫曼编码问题Word下载.docx
- 文档编号:17084492
- 上传时间:2022-11-28
- 格式:DOCX
- 页数:19
- 大小:79.45KB
分治法解决合并排序问题及动态规划解决矩阵连乘和最长公共子序列问题及贪心法解决哈夫曼编码问题Word下载.docx
《分治法解决合并排序问题及动态规划解决矩阵连乘和最长公共子序列问题及贪心法解决哈夫曼编码问题Word下载.docx》由会员分享,可在线阅读,更多相关《分治法解决合并排序问题及动态规划解决矩阵连乘和最长公共子序列问题及贪心法解决哈夫曼编码问题Word下载.docx(19页珍藏版)》请在冰豆网上搜索。
n]的计算量+A[1:
k]*A[k+1:
n]则矩阵子链A[1:
k]和A[k+1:
n]的计算次序也必最优。
[递推关系]
设计算A[i:
j]=Ai…Aj所需最少次数乘法为m[i][j],Ai的维数设为matrix[i].row*matrix[i].col。
[构造最优解]
记m[i][j]的断开位置k为s[i][j],在计算出m[i][j]后,可由s[i][j]递归构造相应的最优解。
字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列。
令给定的字符序列x=“x0,x1,…,x(m-1)”,序列y=“y0,y1,…,y(k-1)”是x的子序列,存在x的一个严格递增下标序列<
i0,i1,…,i(k-1)>
,使得对所有的j=0,1,…,k-1,有xij=yj。
引进一个二维数组c[][],用c[i][j]记录x[i]与y[j]的LCS的长度,b[i][j]记录c[i][j]是通过哪一个子问题的值求得的,以决定搜索的方向。
由自底向上进行递推计算,那么在计算c[i,j]之前c[i-1][j-1],c[i-1][j]与c[i][j-1]均已计算出来。
此时我们根据x[i]=y[j]还是x[i]!
=y[j],就可以计算出c[i][j]。
问题的递归式写成:
将问题的求解过程看作一系列选择,每次选择都是当前状态下的局部最优解。
每作一次选择后,所求问题会简化为一个规模更小的子问题。
从而通过每一步的最优解逐步达到整体最优解。
[问题描述]
通讯过程中需将传输的信息转换为二进制码。
由于英文字母使用频率不同,若频率高的字母对应短的编码,频率低的字母对应长的编码,传输的数据总量就会降低。
要求找到一个编码方案,使传输的数据量最少。
哈夫曼编码就是一种最佳编码方案。
1)以n个字母为结点构成n棵仅含一个点的二叉树集合,字母的频率即为结点的权。
2)每次从二叉树集合中找出两个权最小者合并为一棵二叉树:
增加一个根结点将这两棵树作为左右子树。
新树的权为两棵子树的权之和。
3)反复进行步骤2)直到只剩一棵树为止。
四、详细设计与实现
1、合并排序
例:
序列分解过程:
{8473652}
{8473}{652}
{84}{73}{65}{2}
初始序列aa[0]a[1]a[2]a[3]a[4]a[5]a[6]
{8}{4}{7}{3}{6}{5}{2}
排序后归并到b{48}{73}{65}{2}
复制到a{48}{73}{65}{2}
排序后归并到b{3478}{256}
复制到a{3478}{256}
排序后归并到b{2345678}
复制到a{2345678}
最终结果为:
{2345678}
C++实现代码为:
#include<
iostream>
usingnamespacestd;
voidMerge(inta[],intb[],intl,intm,intr)
{//合并a[l:
m]和b[m+1:
r]存入到b[l:
r]中
inti=l,j=m+1,k=l;
while((i<
=m)&
&
(j<
=r))
if(a[i]<
=a[j])b[k++]=a[i++];
elseb[k++]=a[j++];
if(i>
m)
for(intq=j;
q<
=r;
q++)
b[k++]=a[q];
else
for(intq=i;
=m;
b[k++]=a[q];
}
voidCopy(inta[],intb[],ints,intn)
{
for(inti=s;
i<
=n;
i++)
a[i]=b[i];
voidMergeSort(inta[],intleft,intright)
inti;
if(left<
right)//至少有2个元素
{
i=(left+right)/2;
//取中点
intb[100];
MergeSort(a,left,i);
//递归调用分别对两个字问题排序
MergeSort(a,i+1,right);
Merge(a,b,left,i,right);
//合并到数组b
Copy(a,b,left,right);
//复制回数组a
}
intmain()
inta[100];
intn,i;
cout<
<
"
输入元素个数n:
;
cin>
>
n;
输入一维数组a["
n<
]:
for(i=0;
cin>
a[i];
MergeSort(a,0,n-1);
输出排序为:
for(i=0;
cout<
a[i]<
'
'
endl;
return0;
运行截图:
2、矩阵连乘
A1
A2
A3
A4
A5
A6
30*35
35*15
15*5
5*10
10*20
20*25
结果为:
((A1(A2A3))((A4A5)A6))
C++实现代码:
#include<
#defineMAX100
structMatrix//矩阵
introw;
//矩阵行数
intcol;
//矩阵列数
};
//矩阵
Matrixmatrix[MAX];
//m[i][j]存储Ai到Aj的最小乘法次数
intm[MAX][MAX];
//s[i][j]存储Ai到Aj之间加括号的位置
ints[MAX][MAX];
//矩阵个数
intn;
voidMaxtrixChain(Matrixmatrix[MAX],intn,intm[MAX][MAX],ints[MAX][MAX])
{//计算m[][]和s[][]
for(intr=2;
r<
r++)
for(inti=1;
=n-r+1;
{
intj=i+r-1;
m[i][j]=m[i+1][j]+matrix[i].row*matrix[i].col*matrix[j].col;
s[i][j]=i;
for(intk=i+1;
k<
j;
k++)
{
intt=m[i][k]+m[k+1][j]+matrix[i].row*matrix[k].col*matrix[j].col;
if(t<
m[i][j])
{
m[i][j]=t;
s[i][j]=k;
}
}
}
voidmatrixMultiply(Matrixmatrix[MAX],intn)
boolflag=false;
//标识矩阵的阶数是否要重新输入
cout<
请输入每个矩阵行数与列数:
for(i=1;
A"
行数:
matrix[i].row;
列数:
matrix[i].col;
//检查Ai的列数是否等于Ai+1的行数
if(matrix[i].col!
=matrix[i+1].row)
输入的矩阵不可乘,请重新输入!
flag=true;
break;
if(flag)
matrixMultiply(matrix,n);
//打印加括号后的
voidtraceback(inti,intj)
if(i==j)
i;
else
("
traceback(i,s[i][j]);
traceback(s[i][j]+1,j);
)"
voidmain()
//变量m,s初始化
memset(m,0,sizeof(m));
memset(s,0,sizeof(s));
请输入矩阵的个数:
cin>
matrixMultiply(matrix,n);
MaxtrixChain(matrix,n,m,s);
加括号之后:
traceback(1,n);
3、最长公共子序列
x="
cbwdabh"
y="
sdabwyz"
c[i][j]:
b[i][j]:
最终结果为:
dab
voidLCSLength(char*x,char*y,intm,intn,intc[MAX][MAX],intb[MAX][MAX])
{//用b[][]对c[][]中的元素分成三类
inti,j;
for(i=0;
c[i][0]=0;
for(j=1;
j<
j++)
c[0][j]=0;
if(x[i-1]==y[j-1])//第一类c[][]中的元素
c[i][j]=c[i-1][j-1]+1;
b[i][j]=1;
elseif(c[i-1][j]>
=c[i][j-1])//第二类c[][]中元素
c[i][j]=c[i-1][j];
b[i][j]=2;
else//第三类c[][]中元素
c[i][j]=c[i][j-1];
b[i][j]=3;
voidLCS(intb[MAX][MAX],char*x,inti,intj)
if(i==0||j==0)
return;
if(b[i][j]==1)//输出第一类元素对应的x[]
LCS(b,x,i-1,j-1);
x[i-1];
elseif(b[i][j]==2)//输出第二类元素对应的x[]
LCS(b,x,i-1,j);
else//输出第三类元素对应的x[]
LCS(b,x,i,j-1);
charx[MAX];
chary[MAX];
输入字符串x:
x;
输入字符串y:
y;
intb[MAX][MAX];
intc[MAX][MAX];
intm,n;
m=strlen(x);
n=strlen(y);
LCSLength(x,y,m,n,c,b);
最长公共子序列为:
LCS(b,x,m,n);
4、Hufman编码
abcdef
频率:
4513121695
哈夫曼树为:
a:
b:
101
c:
100
d:
111
e:
1101
f:
1100
string>
#defineMAX32767;
typedefstruct//定义哈夫曼结点结构体
intweight;
//权值
intflag;
//标识是否有父母结点
intparent;
//父母结点
intlchild;
//左孩子结点
intrchild;
//右孩子结点
}hnodetype;
typedefstruct//定义哈夫曼编码结构体
intbit[10];
//定义编码数组
intstart;
charleaf;
}hcodetype;
voidhuffman(charcha[],intm[],intn)
inti,j,m1,m2,x1,x2,c,p;
hnodetype*huffnode=newhnodetype[2*n-1];
//动态分配结构体空间
hcodetype*huffcode=newhcodetype[n],cd;
//定义
2*n-1;
i++)//对哈夫曼结点结构体初始化
huffnode[i].weight=0;
huffnode[i].parent=0;
huffnode[i].flag=0;
huffnode[i].lchild=-1;
huffnode[i].rchild=-1;
i++)//给结构体进行赋值
huffnode[i].weight=m[i];
//给哈夫曼结点赋权值
huffcode[i].leaf=cha[i];
//给哈夫曼编码叶子赋字符
n-1;
i++)//找出最小的两个频率树并合并出一个新的树
m1=m2=MAX;
x1=x2=0;
for(j=0;
n+i;
if(huffnode[j].weight<
=m1&
huffnode[j].flag==0)
m2=m1;
x2=x1;
m1=huffnode[j].weight;
x1=j;
elseif(huffnode[j].weight<
=m2&
m2=huffnode[j].weight;
x2=j;
huffnode[x1].parent=n+i;
huffnode[x2].parent=n+i;
huffnode[x1].flag=1;
huffnode[x2].flag=1;
huffnode[n+i].weight=huffnode[x1].weight+huffnode[x2].weight;
huffnode[n+i].lchild=x1;
huffnode[n+i].rchild=x2;
cd.start=n-1;
c=i;
p=huffnode[c].parent;
while(p!
=0)//构建哈夫曼编码权值
if(huffnode[p].lchild==c)
cd.bit[cd.start]=0;
cd.bit[cd.start]=1;
cd.start--;
c=p;
p=huffnode[c].parent;
huffcode[i].leaf<
:
for(j=cd.start+1;
j++)//输出编码值
huffcode[i].bit[j]=cd.bit[j];
cd.bit[j];
huffcode[i].start=cd.start;
delete[]huffcode;
//释放空间
delete[]huffnode;
inti=0,n,m[100],k;
charcha[100];
输入的总字符n:
k=n;
第"
i+1<
个字符为:
cha[i];
字符"
cha[i]<
的个数:
m[i];
每个字符的哈夫曼编码是:
huffman(cha,m,k);
}
五、总结
经过两个星期的计算机算法设计与分析课程设计,终于顺利完成这次课程设计。
通过这次课程设计,收获颇丰。
1、对算法理解更深
通过该课程设计,掌握了计算机算法程序,以及算法的运行原理。
通过VC++6.0编译器编译算法程序,将书上的算法实现在计算机上,把原来以为很深奥的书本知识变的更为简单,对算法原理有更深的理解。
2、对该算法理论在实践中的应用有深刻的理解
通过把算法程序在计算机上实现,知道和理解了算法在计算机中是怎样执行的,对算法理论在实践中的应用有深刻的理解。
3、激发了学习的积极性
通过该课程设计,全面系统的理解了算法的一般原理和基本实现方法。
把死板的课本知识变得生动有趣,激发了学习的积极性。
把学过的计算机算法的知识得到了强化,能够把课堂上学的知识通过自己设计的程序表示出来,加深了对算法理论知识的理解。
以前对与计算机算法的认识是模糊的,概念上的,现在通过自己动手做实验,从实践上认识了算法的作用,对计算机编程能力也有了进一步的提升。
4、理解了该知识点以及学科之间的融合渗透
本次课程设计程序部分是用C++语言编写的,把《数据结构》《计算机算法设计与分析》《C++程序设计》三门学科联系起来,把各个学科之间的知识融合起来,把各门课程的知识联系起来,对计算机学科知识的认识更加深刻,进一步加深了对这三门课程的认识。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 分治 解决 合并 排序 问题 动态 规划 矩阵 最长 公共 序列 贪心 哈夫曼 编码
链接地址:https://www.bdocx.com/doc/17084492.html