最长公共子序列实验报告

合集下载

最长公共子序列(LCS)算法实验

最长公共子序列(LCS)算法实验

试验四.最长公共子序列(LCS)算法一.实验原理对于给定的两个序列A和B,如果序列C既是A的子序列,又是B的子序列,则称C是A和B的公共子序列,A和B的公共子序列可能不止一个,其中最长的那个序列称为公共子序列。

公共子序列在很多实际应用中起关键作用。

序列A={abdledefiess},B={abwdifgdefiesa},最长公共子序列为C={defies}二.实验目的本次实验就是要找出两个序列XY的最长公共子序列LCS三.实验步骤1.查找公共子序列2.输出公共子序列核心算法代码如下:int **lcs_length(char p[],char q[],int **c,int **k,int m,int n){int i,j;for(i=1;i<=m;i++){for(j=1;j<=n;j++){if(p[i-1]==q[j-1])//如果两个字母相等的情况{c[i][j]=c[i-1][j-1]+1;k[i][j]=1;}else{if(c[i-1][j]>=c[i][j-1])//两字母不等情况1{c[i][j]=c[i-1][j];k[i][j]=2;}else//两字母不等情况2{c[i][j]=c[i][j-1];k[i][j]=3;}}}}return c,k;}输出代码void print_lcs(int **k,char p[],int i,int j){if(i==0||j==0)return ;if(k[i][j]==1){print_lcs(k,p,i-1,j-1);//通过递归的方法按照输入的从头到尾的顺序输出LCScout<<p[i-1];}else if(k[i][j]==2)print_lcs(k,p,i-1,j);elseprint_lcs(k,p,i,j-1);}四.实验结果根据实验算法运行结果如下:以上算法表明可以正确的找出两个序列的最长公共子序列,达到了本次实验的目的.。

动态基础设计实验报告(3篇)

动态基础设计实验报告(3篇)

第1篇一、实验目的1. 理解动态规划的基本思想和方法。

2. 掌握动态规划在解决实际问题中的应用。

3. 提高编程能力和算法设计能力。

二、实验内容本次实验主要涉及以下四个问题:1. 斐波那契数列2. 最长公共子序列3. 最长递增子序列4. 零钱找零问题三、实验原理动态规划是一种在数学、管理科学、计算机科学、经济学和生物信息学等领域中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。

动态规划的基本思想是将一个复杂问题分解成若干个相互重叠的子问题,然后按照子问题的顺序逐个求解,最后将这些子问题的解合并成原问题的解。

四、实验步骤及代码实现1. 斐波那契数列斐波那契数列是指这样一个数列:1, 1, 2, 3, 5, 8, 13, 21, ...,其中每个数都是前两个数的和。

```cppinclude <iostream>using namespace std;int Fibonacci(int n) {if (n <= 1) {return 1;}int fib[n+1];fib[0] = 1;fib[1] = 1;for (int i = 2; i <= n; i++) {fib[i] = fib[i-1] + fib[i-2];}return fib[n];}int main() {int n;cout << "请输入斐波那契数列的项数:" << endl;cin >> n;cout << "斐波那契数列的第 " << n << " 项为:" << Fibonacci(n) << endl;return 0;}```2. 最长公共子序列给定两个序列A和B,找出它们的公共子序列中长度最长的序列。

```cppinclude <iostream>using namespace std;int LCSLength(string X, string Y) {int m = X.length();int n = Y.length();int L[m+1][n+1];for (int i = 0; i <= m; i++) {for (int j = 0; j <= n; j++) {if (i == 0 || j == 0)L[i][j] = 0;else if (X[i-1] == Y[j-1])L[i][j] = L[i-1][j-1] + 1;elseL[i][j] = max(L[i-1][j], L[i][j-1]);}}return L[m][n];}int main() {string X = "AGGTAB";string Y = "GXTXAYB";cout << "最长公共子序列长度为:" << LCSLength(X, Y) << endl; return 0;}```3. 最长递增子序列给定一个序列,找出它的最长递增子序列。

最长公共子序列实验报告

最长公共子序列实验报告
4. for j0 to m
5. L[0,j]0
6. end for
7. for i1 to n
8. for j1 to m
9. if ai=bj then L[i,j]L[i-1,j-1]+1
10. else L[i,j]max {L[i,j-1], L[i-1,j] }
11. end if
12. end for
六、指导教师评语及成绩
评语:
年月日
设计题目
求最长公共子序列
一、设计内容
求最长公共子序列,如输入字符串str1=adadsda,str2=sadasfda。
则求出的最长公共子序列是adasda。
二、设计目的
掌握动态规划思想,对使用求最长公共子序列加深理解。
三、设计过程
1.算法设计
1. for i0 to n
2. L[i,0]0
3. end for
13. end for
14. return L[n,m]
2.流程图
图1.Lcs算法
3.数据结构
str1=adadsda
str2=sadasfda
四、程序实现及运行结果
五、设计总结
通过此次实验,我更加深刻的理解了动态规划的思想,提高了我的动手实践的能力对我之后的发展起了很大的帮助,动态规把多阶段过程转化为一系列单阶段问题,利用各阶段之间的关系,逐个求解。
河北地质大学
课程设计报告
(学院)系:信息工程学院
专业:计算机科学与技术
*******
班级:二班
学号:************
**********ቤተ መጻሕፍቲ ባይዱ
2016年11月26日
算法课程设计报告

最长公共子序列实验报告

最长公共子序列实验报告

最长公共子序列问题一.实验目的:1.加深对最长公共子序列问题算法的理解,实现最长公共子序列问题的求解算法;2.通过本次试验掌握将算法转换为上机操作;3.加深对动态规划思想的理解,并利用其解决生活中的问题。

二.实验内容:1.编写算法:实现两个字符串的最长公共子序列的求解;2.将输入与输出数据保存在文件之中,包括运行时间和运行结果;3.对实验结果进行分析。

三.实验操作:1.最长公共子序列求解:将两个字符串放到两个字符型数组中,characterString1和characterString2,当characterString1[m]= characterString2[m]时,找出这两个字符串m之前的最长公共子序列,然后在其尾部加上characterString1[m],即可得到最长公共子序列。

当characterString1[m] ≠characterString2[m]时,需要解决两个子问题:即找出characterString1(m-1)和characterString2的一个最长公共子序列及characterString1和characterString2(m-1)的一个最长公共子序列,这两个公共子序列中较长者即为characterString1和characterString2的一个最长公共子序列。

2.动态规划算法的思想求解:动态规划算法是自底向上的计算最优值。

计算最长公共子序列长度的动态规划算法LCS-Length以characterString1和characterString2作为输入,输出两个数组result和judge1,其中result存储最长公共子序列的长度,judge1记录指示result的值是由那个子问题解答得到的,最后将最终的最长公共子序列的长度记录到result中。

以LCS-Length计算得到的数组judge1可用于快速构造序列最长公共子序列。

首先从judge1的最后开始,对judge1进行配对。

算法课设实验报告(3篇)

算法课设实验报告(3篇)

第1篇一、实验背景与目的随着计算机技术的飞速发展,算法在计算机科学中扮演着至关重要的角色。

为了加深对算法设计与分析的理解,提高实际应用能力,本实验课程设计旨在通过实际操作,让学生掌握算法设计与分析的基本方法,学会运用所学知识解决实际问题。

二、实验内容与步骤本次实验共分为三个部分,分别为排序算法、贪心算法和动态规划算法的设计与实现。

1. 排序算法(1)实验目的:熟悉常见的排序算法,理解其原理,比较其优缺点,并实现至少三种排序算法。

(2)实验内容:- 实现冒泡排序、快速排序和归并排序三种算法。

- 对每种算法进行时间复杂度和空间复杂度的分析。

- 编写测试程序,对算法进行性能测试,比较不同算法的优劣。

(3)实验步骤:- 分析冒泡排序、快速排序和归并排序的原理。

- 编写三种排序算法的代码。

- 分析代码的时间复杂度和空间复杂度。

- 编写测试程序,生成随机测试数据,测试三种算法的性能。

- 比较三种算法的运行时间和内存占用。

2. 贪心算法(1)实验目的:理解贪心算法的基本思想,掌握贪心算法的解题步骤,并实现一个贪心算法问题。

(2)实验内容:- 实现一个贪心算法问题,如活动选择问题。

- 分析贪心算法的正确性,并证明其最优性。

(3)实验步骤:- 分析活动选择问题的贪心策略。

- 编写贪心算法的代码。

- 分析贪心算法的正确性,并证明其最优性。

- 编写测试程序,验证贪心算法的正确性。

3. 动态规划算法(1)实验目的:理解动态规划算法的基本思想,掌握动态规划算法的解题步骤,并实现一个动态规划算法问题。

(2)实验内容:- 实现一个动态规划算法问题,如背包问题。

- 分析动态规划算法的正确性,并证明其最优性。

(3)实验步骤:- 分析背包问题的动态规划策略。

- 编写动态规划算法的代码。

- 分析动态规划算法的正确性,并证明其最优性。

- 编写测试程序,验证动态规划算法的正确性。

三、实验结果与分析1. 排序算法实验结果:- 冒泡排序:时间复杂度O(n^2),空间复杂度O(1)。

算法设计与分析实验报告-动态规划寻找最长公共子序列

算法设计与分析实验报告-动态规划寻找最长公共子序列

实验报告一、实验目的写出你认为比较重要的实验目的1.理解动态规划的基本思想,了解最优子结构性质和子问题的重叠性质。

2.熟练掌握典型的动态规划问题。

掌握动态规划思想分析问题的一般方法,对较简单的问题能正确分析,并设计出动态规划算法,并能够用程序实现。

二、实验内容简短明确地写出实验的内容(选作题目)动态规划寻找最长公共子序列三、实验环境操作系统、调试软件名称、版本号,上机地点,机器台号Win10、dev-cpp5.2.0、dreamweaver cs6四、问题分析(1)分析要解决的问题,给出你的思路,可以借助图表等辅助表达。

当一个问题具有最优子结构时,我们就可以考虑使用动态规划法去实现,因此首先刻画最长公共子序列的最优子结构:设X=x1x2…xm和Y=y1y2…yn是两个序列,Z=z1z2…zk是这两个序列的一个最长公共子序列。

1. 如果xm=yn,那么zk=xm=yn,且Zk-1是Xm-1,Yn-1的一个最长公共子序列;2. 如果xm≠yn,那么zk≠xm,意味着Z是Xm-1,Y的一个最长公共子序列;3. 如果xm≠yn,那么zk≠yn,意味着Z是X,Yn-1的一个最长公共子序列。

从上面我们可以看出如果xm=yn,那么我们应该求解Xm-1,Yn-1的一个LCS,并且将xm=yn加入到这个LCS的末尾,这样得到的一个新的LCS就是所求。

如果xm≠yn,分别求Xm-1,Y的一个LCS和X,Yn-1的一个LCS。

其中较长者就是X和Y的一个LCS。

c[m][n]=c[m-1][n-1]+1;c[m][n]=max(c[m-1][n],c[m][m-1]);(2)分析利用你的想法解决该问题可能会有怎样的时空复杂度。

建立c[m][n]的过程中时间复杂度是Ο(mn),空间复杂度是Ο(mn)。

(3)其它(你认为需要在此说明的)五、问题解决(1)根据对问题的分析,写出解决办法。

计算最长公共子序列长度的动态规划算法LCSLength以x[]和y[]作为输入,输出两个数组b[][]和c[][],其中c[][]存储最长公共子序列的长度,b[][]记录指示c[][]的值是由那个子问题解答得到的,最后将最终的最长公共子序列的长度记录到c[][]中。

最长公共子序列算法分析

最长公共子序列算法分析

求连续的最长公共子串•首先我们来分析一个简单例子。

•LCS(‘212325233’,’312123223’)=‘21232’•我们看是如何求解出来的,如下图,红色下划线表示已匹配。

分析•从前面例子可以看出解题思路:•每次都是将子串的每一位与母串的每一位比较,然后根据比较的结果找LCS。

因此,我们需要借助一个二维数组存储两个串比较后的结果,用1表示匹配成功,0表示不成功。

如匹配结果如下图(1),最长公共子串见图(2)。

进一步分析•在0和1的矩阵中找最长的1对角线序列又要花去一定的时间。

通过改进矩阵的生成方式和设置标记变量,可以省去这部分时间。

下面是新的矩阵生成方式:算法•设置一个矩阵,记录两个串的匹配情况。

•当字符匹配的时候,不是简单的给相应元素赋上1,而是赋上其左上角元素的值加1。

•我们用两个标记变量来标记矩阵中值最大的元素的位置,在矩阵生成的过程中来判断•当前生成的元素的值是不是最大的,据此来改变标记变量的值,那么到矩阵完成的时候,最长匹配子串的位置和长度就已经出来了。

•显然该算法的时间复杂度为两个串的长度乘积。

for(i=1;i<=row;i++) {for(j=1;j<=col;j++) {if(s[i-1]==rs[j-1]) {lcs[i][j]=lcs[i-1][j-1]+1;}else{if(lcs[i-1][j]>=lcs[i][j-1]) {lcs[i][j]=lcs[i-1][j];}else {lcs[i][j] = lcs[i][j-1];}}}}return lcs[row][col];}。

最长公共子序列(LCS)算法实验

最长公共子序列(LCS)算法实验
三.实验步骤
.查找公共子序列
.输出公共子序列
核心算法代码如下:
**( [] [] ** ** )资料个人收集整理,勿做商业用途
{
;
(<)
{
(<)
{
([][])如果两个字母相等地情况
{
[][][][];
[][];
}
{
([][]>[][])两字母不等情况
{
[][][][];
[][];
}
两字母不等情况
{
[][][][];
一.实验原理
对于给定地两个序列和,如果序列既是地子序列,又是地子序列,则称是和地公共子序列,和地公共子序列可能不止一个,其中最长地那个序列称为公共子序列.公共子序列在很多实际应用中起关键作用.资料个人收集整理,勿做商业用途
序列{}{},最长公共子序列为{}资料个人收集整理,勿做商业用途
二.实验目地
本次实验就是要找出两个序列地最长公共子序列
[][];
}
}
}
}
;
}
输出代码
( ** [] )
{
()
;
([][])
{
()通过递归地方法按照输入地从头到尾地顺序输出
<<[];}([][])Fra bibliotek();
();
}
四.实验结果
根据实验算法运行结果如下:
以上算法表明可以正确地找出两个序列地最长公共子序列,达到了本次实验地目地.
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

最长公共子序列问题
一.实验目的:
1.加深对最长公共子序列问题算法的理解,实现最长公共子序列问题的求解算法;
2.通过本次试验掌握将算法转换为上机操作;
3.加深对动态规划思想的理解,并利用其解决生活中的问题。

二.实验内容:
1.编写算法:实现两个字符串的最长公共子序列的求解;
2.将输入与输出数据保存在文件之中,包括运行时间和运行结果;
3.对实验结果进行分析。

三.实验操作:
1.最长公共子序列求解:
将两个字符串放到两个字符型数组中,characterString1和characterString2,当characterString1[m]= characterString2[m]时,找出这两个字符串m之前的最长公共子序列,然后在其尾部加上characterString1[m],即可得到最长公共子序列。

当characterString1[m] ≠characterString2[m]时,需要解决两个子问题:即找出characterString1(m-1)和characterString2的一个最长公共子序列及characterString1和characterString2(m-1)的一个最长公共子序列,这两个公共子序列中较长者即为characterString1和characterString2的一个最长公共子序列。

2.动态规划算法的思想求解:
动态规划算法是自底向上的计算最优值。

计算最长公共子序列长度的动态规划算法LCS-Length以characterString1和characterString2作为输入,输出两个数组result和judge1,其中result存储最长公共子序列的长度,judge1记录指示result的值是由那个子问题解答得到的,最后将最终的最长公共子序列的长度记录到result中。

以LCS-Length计算得到的数组judge1可用于快速构造序列最长公共子序列。

首先从judge1的最后开始,对judge1进行配对。

当遇到“↖”时,表示最长公共子序列是由characterString1(i-1)和characterString2(j-1)的最长公共子序列在尾部加上characterString1(i)得到的子序列;当遇到“↑”时,表示最长公共子序列和characterString1(i-1)与characterString2(j)的最长公共子序列相同;当遇到“←”时,表示最长公共子序列和characterString1(i)与characterString2(j-1)的最长公共子序列相同。

如图所示:
时间复杂度公式:
代码实现:
void LCSLength(char* characterString1,char*
characterString2,int length1,int length2,int
judge[][10000]){
int result[100][100];
for(int i=0;i<=length1;i++) result[i][0]=0;
for(int j=1;j<=length2;j++) result[0][j] = 0;
for(int i=1;i<=length1;i++){
for(int j=1;j<=length2;j++){
if(characterString1[i-1]==characterString2[j-1]){ result[i][j]=result[i-1][j-1]+1;
judge[i][j]=0;
}
else if(result[i-1][j]>=result[i][j-1]){
result[i][j]=result[i-1][j];
judge[i][j]=1;
}
else{
result[i][j]=result[i][j-1];
judge[i][j]=-1;
}
}
}
}
void LCS(int judge[][10000],char* characterString1,int length1,int length2){//得到最长公共子序列
if(length1==0||length2==0) return;
if(judge[length1][length2]==0){
LCS(judge,characterString1,length1-1,length2-1);
record(characterString1[length1-1]);//存入文件
cout<<characterString1[length1-1];
}
else if(judge[length1][length2]==1)
LCS(judge,characterString1,length1-1,length2);
else LCS(judge,characterString1,length1,length2-1);
}
3.备忘录算法实现:
备忘录算法是从顶向下计算最优解的思想,备忘录方法的控制结构与直接递归方法的控制结构相同,但备忘录方法用一个表格来保存已解决的子问题的答案,避
免了相同问题的重复求解。

代码实现:
int searchLCS(char* characterString1,char* characterString2,int length1,int length2){
if(judge2[length1][length2]>-1) return
judge2[length1][length2];
if(length1==0||length2==0) judge2[length1][length2]=0;
else{
if(characterString1[length1-1]==characterString2[length2-
1])
judge2[length1][length2]=searchLCS(characterString1,charact
erString2,length1-1,length2-1)+1;
else
judge2[length1][length2]=max(searchLCS(characterString1,cha
racterString2,length1,length2-1),
searchLCS(characterString1,characterString2,length1-
1,length2));
}
return judge2[length1][length2];
}
int memorizedLCS(char* characterString1,char* characterString2){ int length1=strlen(characterString1);
int length2=strlen(characterString2);
for(int i=1;i<=length1;i++)
for(int j=1;j<=length2;j++)
judge2[i][j]=-1;
return
searchLCS(characterString1,characterString1,length1,length2);
}
4.递归法:
设有字符串characterString1和characterString2,当两个数组的对应位置的字符相同时,则直接求解下一个位置,当不同时取两种情况中的最大值。

时间复杂度公式:
代码实现:
int recursionLCS(int i,int j,int length1){
if(i>=length1||j>=length2) return 0;
if(characterString1[i]==characterString2[j]) return 1+recursionLCS(i+1,j+1);
else return
recursionLCS(i+1,j)>recursionLCS(i,j+1)?recursionLCS(i+1,j)
:recursionLCS(i,j+1);
}
5.穷举法:
将数组characterString1和characterString2两个字符串的所有字串求出,并将这些字串相互比较,直到找的最长公共子序列为止,当字符串的长度很长时,所要求取的子串序列相当多,故所开销的时间最多。

四.实验结果分析:
当输入字符串长度分别为(20,20),(34,78),(98,145)时,在动态规划算法、备忘录算法、递归算法得到的时间分别为(0,0,0),(0,16,22),
(0,16,34),由于在多次测量下不稳定,故不做具体展示。

得到上述情况是由于生成的字符串具有不确定性,以及代码的不完善,不能对大数据进行时间测量。

五.实验感受:
本次实验对字符串的反复递归,对栈的操作经常发生访问冲突的错误,故只能才用少量的数据处理,并且当数据存放到文件中时,子函数和主函数对同一文件的操作有覆盖和不显示的问题,故创建了两个文本文件用于对实验结果的存放。

相关文档
最新文档