文档库 最新最全的文档下载
当前位置:文档库 › 串的应用求两个串的最长公共子串(附答案)

串的应用求两个串的最长公共子串(附答案)

串的应用求两个串的最长公共子串(附答案)
串的应用求两个串的最长公共子串(附答案)

实验八《串的应用》实验-----求两个串的最长公共子串

(一)实验目的

掌握顺序串的基本操作。

(二)实验内容与要求

1、采用顺序存储结构用户输入的两个串,输出这两个串的最长公共子串

2、问题描述

先给最长公共子串的下标index和长度maxlen均赋值为0。

设s=”a0a1……a n”,t=”b0b1……b m”,扫描串s,对于当前字符a i,扫描t,若b j=a i, 计算它们其后相同字符的个数,并赋给leng,若leng>maxlen,说明它是当前最长公共子串,则index=i,然后继续扫描t,直到t完毕。当t完毕后,又继续扫描s,直到s完毕。这样s 串中从index开始的maxlen个字符构成的串便是最长子串。

(三)算法

1、数据类型定义

struct str{

char vec[MAXCHAR];

int len;

};

2、操作算法

(1)找最长公共子串算法

void maxcomstr(struct str *s, struct str *t)

{同学们自己编写

}

(2)主函数main( )

3、程序

#include

#include< iostream.h >

#include

#define MAXCHAR 30

struct str{

char vec[MAXCHAR];

int len;

};

找最长公共子串算法

void maxcomstr(struct str *s,struct str *t)

{int index=0,maxlen=0,i=0,j,k,leng;

while (ilen)

{_____________________

while (jlen)

{if (____________________________)

{ leng=1;

for (k=1;s->vec[i+k]==t->vec[j+k];k++)

_______________________

if (leng>maxlen)

{ index=i;

_________________________}

j+=leng;

}

else j++;

i++;}}

printf("\n字符串%s和%s的最长公共子串:",s->vec,t->vec); for (i=0;i

printf("%c",s->vec[index+i]);

printf("\n");

}

void main( )

{ struct str *r,*r1;

r=new str; r1=new str;

cout<<”输入第一个字符串:”;

sanf(“%s”,r->vec);

r->len=strlen(r->vec);

cout<<”输入第二个字符串:”;

sanf(“%s”,r1->vec);

r1->len=strlen(r1->vec);

maxcomstr(r,r1);

}

(四)实验结果

1、求两个串”ababcabcdabcde”和“xyabcdxy”的最长公共子串。

2、程序执行过程:请同学们写出

3.分析程序并给出小结、体会。

答案下页

最长公共子序列问题(最)

算法作业: LCS 问 题 作业要求:设计一个算法求出两个序列的所有LCS ,分析最坏情况,用“会计方法”证明利用b[i][j]求出 所有LCS 的算法在最坏情况下时间复杂度为)(m m n C O + 1、 算法思路: 根据最长公共子序列问题的性质,即经过分解后的子问题具有高度重复性,并且具有最优子结构性质,采用动态规划法求解问题。设X={x 1, x 2, … , x n }, Y={y 1, y 2, … , y m }, 首先引入二维数组C[i][j]记录X i 和Y j 的LCS 的长度,定义C[i][j]如下: { j i j y i 且x ,i,j ]][j C[i j y i x j i j i C j i C j i C 00001110,]},1][[],][1[max{]][[===>+--≠>--=或,且 为了构造出LCS ,还需要使用一个二维数组b[m][n],b[i][j]记录C[i][j]是通过哪个子问题的值求得 的,以决定搜索的方向,欲求出所有的LCS ,定义数组b 如下: 设1-对角线方向;2-向上;3-向左;4-向上或向左 若X[i]=Y[j],b[i][j] = 1, 若C[i-1][j][i][j-1], 则b[i][j] = 3, 若C[i-1][j]=[i][j-1], 则b[i][j] = 4, 根据以上辅助数组C 和b 的定义,算法首先需要求出这两个数组, C[m][n]中记录的最长公共子序列的长度,b 中记录了查找子序列元素的搜索方向。 利用C 和b 的信息,Find_All_LCS 可以采用回溯法求出所有的LCS 。基本思路如下:使用一个辅助数组记录每次调用Find_All_LCS 得到的LCS 中的元素,每次递归调用一次Find_All_LCS ,进入一个新的执行层,首先要判断当前处理的两个子序列长度是否大于等于0 ,若不满足,则该层的递归结束,返回上一层;然后再判断当前得到的子序列是否等于数组C 中求出的最长公共子序列长度,若等于,则说明算法执行到此已经得到一个LCS ,按序输出;若不等于,此时根据数组b 中记录的搜索方向继续搜索,特别要说明的是,当b[i][j]=4时,即要向上或向左,需要对这两个方向分别调用Find_All_LCS ,保证沿着这两个方向上LCS 元素不被漏掉,都可以搜索到;若b[i][j]=1,即沿对角线方向搜索前进时,此时元素X[i]为LCS 中的元素,存放至辅助数组中去,同时将当前已经求得的LCS 长度增1,当递归调用Find_All_LCS 从b[i][j]=1处时,需要回溯一步,搜索其它路径上可能为LCS 中的元素。当所有的可能路径都已经搜索完,算法结束。 对于某些情况会输出重复的LCS ,这是因为算法在沿不同路径搜索时可能会出现相同的LCS 序列。 2、 时间复杂度分析 由上述对Find_All_LCS 算法的分析可知,求出所有的LCS 实际上是根据搜索的方向信息遍历所有的路径找出满足条件的元素集合。因此,除求解辅助数组C 和b 所用的O(mn+m+n)的执行时间外,Find_All_LCS 的时间复杂度取决于所遍历路径数。而路径数是由搜索方向决定的。显然算法在最好的情况下,即m=n 并且b 中所有的值都指示沿着对角线方向搜索,时间复杂度为O(n). 相反,当X 和Y 序列不存在公共子序列时为算法的最坏情况,此时C 中所有值都等于0,数组b 中所有的值都指示要分别沿两个不同的方向(向左或向上)搜索,这种情况下每处理一次X[i],Y[j]时总是要沿两个方向分别调用Find_All_LCS ,遇到i=0或j=0时返回,直到搜索完所有的可能路径才结束,最坏情况下的搜索矩阵如下图所示:

最长公共子序列(LCS)问题

程序员编程艺术第十一章:最长公共子序列(LCS)问题 0、前言 程序员编程艺术系列重新开始创作了(前十章,请参考程序员编程艺术第一~十章集锦与总结)。回顾之前的前十章,有些代码是值得商榷的,因当时的代码只顾阐述算法的原理或思想,所以,很多的与代码规范相关的问题都未能做到完美。日后,会着力修善之。 搜遍网上,讲解这个LCS问题的文章不计其数,但大多给读者一种并不友好的感觉,稍感晦涩,且代码也不够清晰。本文力图避免此些情况。力保通俗,阐述详尽。同时,经典算法研究系列的第三章(三、dynamic programming)写的极其糟糕,所以,也算是对那文的一种弥补。有任何问题,欢迎不吝赐教。 第一节、问题描述 什么是最长公共子序列呢?好比一个数列S,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则S称为已知序列的最长公共子序列。 举个例子,如:有两条随机序列,如1 3 4 5 5 ,and 2 4 5 5 7 6,则它们的最长公共子序列便是:4 5 5。 第二节、LCS问题的解决思路 ?穷举法 解最长公共子序列问题时最容易想到的算法是穷举搜索法,即对X的每一个子序列,检查它是否也是Y的子序列,从而确定它是否为X和Y的公共子序列,并且在检查过程中选出最长的公共子序列。X和Y的所有子序列都检查过后即可求出X和Y的最长公共子序列。X的一个子序列相应于下标序列{1, 2, …, m}的一个子序列,因此,X共有2m个不同子序列(Y亦如此,如为2^n),从而穷举搜索法需要指数时间(2^m * 2^n)。 ?动态规划算法 事实上,最长公共子序列问题也有最优子结构性质。 记: Xi=﹤x1,?,xi﹥即X序列的前i个字符(1≤i≤m)(前缀) Yj=﹤y1,?,yj﹥即Y序列的前j个字符(1≤j≤n)(前缀) 假定Z=﹤z1,?,zk﹥∈LCS(X , Y)。

求最长子序列的长度

一,最长递增子序列问题的描述 设L=是n个不同的实数的序列,L的递增子序列是这样一个子序列Lin=,其中k1是对序列L=按递增排好序的序列。那么显然X与L的最长公共子序列即为L的最长递增子序列。这样就把求最长递增子序列的问题转化为求最长公共子序列问题LCS了。 最长公共子序列问题用动态规划的算法可解。设Li=< a1,a2,…,a i>,Xj=< b1,b2,…,b j>,它们分别为L和X的子序列。令C[i,j]为Li与Xj的最长公共子序列的长度。则有如下的递推方程: 这可以用时间复杂度为O(n2)的算法求解,由于这个算法上课时讲过,所以具体代码在此略去。求最长递增子序列的算法时间复杂度由排序所用的O(nlogn)的时间加上求LCS的O(n2)的时间,算法的最坏时间复杂度为O(nlogn)+O(n2)=O(n2)。 三,第二种算法:动态规划法 设f(i)表示L中以a i为末元素的最长递增子序列的长度。则有如下的递推方程: 这个递推方程的意思是,在求以a i为末元素的最长递增子序列时,找到所有序号在L前面且小于a i的元素a j,即j

最长公共子序列实验报告

河北地质大学课程设计报告 (学院)系: 信息工程学院 专业: 计算机科学与技术 姓名: 李义 班级: 二班 学号: 515109030227 指导教师: 王培崇 2016年11月26 日

算法课程设计报告 姓名李义学号515109030227 日期2016/11/10-2016/12/1 实验室152 指导教师王培崇设备编号08 设计题目求最长公共子序列 一、设计内容 求最长公共子序列,如输入字符串str1=adadsda,str2=sadasfda。 则求出的最长公共子序列是adasda。 二、设计目的 掌握动态规划思想,对使用求最长公共子序列加深理解。 三、设计过程 1.算法设计 1. for i ←0 to n 2. L[i,0] ←0 3. end for 4. for j ←0 to m 5. L[0,j] ←0 6. end for 7. for i ←1 to n 8. for j ←1 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 13. end for 14. return L[n,m] 2.流程图

开始结束 输入I=0,j=0 i<=n L[I,0]=0 i++ Y L[0,j]=0 N j<=n j++ Y i=1 to n J=1 to m ai=bj L[i,j]=L[i-1,j-1]+1 L[i,j]=max{L[i-1,j ],L[i,j-1]} Y J++i++ N 图1.Lcs 算法 3.数据结构 str1=adadsda str2=sadasfda 四、程序实现及运行结果

2006级计算机科学系_程序设计_A卷

中山大学计算机科学系2006级 计算机科学与技术专业、网络工程专业、信息安全专业(ABCDE班) 程序设计 A卷 学号 ____________ 姓名 ______________ 成绩______________ (试卷共6页,答案全写在答题纸上,交卷时连试卷一同交回) 考试形式:闭卷任课老师:林瑛、肖菁、杨永红2007-6 《中山大学授予学士学位工作细则》第六条:“考试作弊不授予学士学位。” 一、单项选择(每小题1分,共15分) 1.C++语言新引入了在一种C语言中没有的参数传递方式是: A) 按指针调用B) 按名调用C) 按值调用D) 按引用调用 2.在C++语言中,以下哪个表达式采用了八进制表示整型常量: A) k=0123; B) k=123; C) k=’\x23’; D) k=0x123; 3.下面对结构或类中成员的访问不正确的是: A). *p.salary B) p->salary (p为指向类对象的指针) (p为指向类对象的指针) C) (*p).salary D) Worker.salary (p为指向类对象的指针) (Worker是类类型的对象) 4.类A中有一成员函数说明如下void A::Set(A & a); 其中A & a的含义是: A) 指向类A的指针为a B) 变量A与a按位与作为函数Set()的参数 C) 将a的地址值赋给变量Set D) a是类A的对象引用,用作函数Set()的形参 5.假定一个类有两个数据成员a和b,其构造函数为: A(int aa=1,int bb=0){ a = aa; b = bb; } 则执行语句A x(4); 后,x.a和x.b值分别是: A) 1和0 B) 1和4 C) 4和0 D) 4和1 6.可以用友元方式重载的运算符是: A) + :: << B) = >> / C) + & [] D) + || ! 7.设有如下声明的类: class FOO { private: static float std; float max, min; }; 则表达式sizeof(FOO)的值为: A) 4 B) 8 C) 12 D) 16 8.若在一个类中用成员函数重载了某种二元运算符@,而obj1和obj2都是该类的对象,则表达式 obj1@obj2 被C++编译器解释为: A) obj1.operator@(obj2) B) obj2.operator@(obj1) C) operator@(obj1,obj2) D) operator@(obj2,obj1) 9.下列函数中,不能重载的是: A) 类的成员函数B) 非成员函数C) 析构函数D) 构造函数 10.关于构造函数不正确的说法是: A) 构造函数可以有返回值B) 一个类可以有多个构造函数 C) 构造函数名与类名相同D) 构造函数初始化时为对象开辟一个内存

2016Nuist程序设计竞赛

1.莱布尼兹的最值 描述 莱布尼兹是德国哲学家、数学家,历史上少见的通才,被誉为十七世纪的亚里士多德。他和牛顿分别创立了微积分,而且在几何意义和符号记法上都要比牛顿高明。但是牛顿一直以皇家学会会长的身份打压势单力薄的莱布尼兹,欺骗世人。莱布尼兹含恨而死,但是历史最终还给了莱布尼兹一个清白,他说:“我穷尽我的一生的研究,包括我所创立的微积分都在研究一个问题,那就是最值。” 所以,莱布尼兹留下的是一个关于最值的问题. 输入 第一行一个整数n(n<=100),表示数据的个数。 接下来n行输入n个不同的正整数,莱布尼兹并不想为难大家所以数据都很小。 输出 输出一行:表示这n个数里面的最小值 样例输入 5 120 80 150 100 90 样例输出 80

2.欧几里得的公约数 描述 古希腊数学家欧几里得被称为“几何之父”,他最著名的著作《几何原本》是欧洲数学的基础,提出五大公式,欧几里得几何,被广泛的认为是历史上最成功的教科书。欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数,至今仍然被广泛运用。 欧几里得留下了n+1个数。 输入 第一个数为n,后面有n个数,请你计算出这n个数有多少与n互质(公约数只有1) 输出 整数n与其后的n个数互质的个数 样例输入 5 8 10 12 14 15 样例输出 3

3.图灵的密码 描述 图灵,英国数学家、逻辑学家,被称为计算机之父,人工智能之父。第二次世界大战其间,德国研制的密码机enigma让英国即使拦截到了消息也束手无策。1939年秋,图灵应召到英国外交部通信处从事军事工作,主要是破译enigma的工作。那时候破译都是用纸和笔计算但是德国人每天都会更换密钥,破译几乎不可能。就在人们一筹莫展的时候,图灵说:“只有机器才能战胜机器”,不顾世人的嘲讽开始制造大型机,最终破译成功帮助盟友取得了二战的胜利。 图灵留下的是加密算法,用0来对应一个“.”和四个“-”的组合,用1来对应两个“.”和三个“-”的组合......其余对照方式如下: 0 .---- 1 ..--- 2 ...-- 3 ....- 4 ..... 5 -.... 6 --... 7 ---.. 8 ----. 9 ----- 每行密码都以“-”开头和结束,每个电码间用一个“-”隔开 输入 输入一行数字明文,请你给出相应的密码。 输出 输出密码 样例输入 01 样例输出 -.-----..----

动态规划解最长公共子序列问题

动态规划解最长公共子序列问题 动态规划主要针对最优化问题,它的决策是全面考虑不同的情况分别进行决策,,最后通过多阶段决策逐步找出问题的最终解.当各个阶段采取决策后,会不断决策出新的数据,直到找到最优解.每次决策依赖于当前状态,又随机引起状态的转移.一个决策序列就是在变化的状态中产生出来的,故有”动态”的含义.所以,这种多阶段最优化决策解决问题的过程称为动态规划. 一问题的描述与分析 字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干字符(可能一个也不去掉)后形成的字符序列..令给定的字符序列X=”x0,x1,x2,…xm-1”,序列Y=”y0,y1,…yk-1”是X的子序列,存在X的一个严格递增下标序列i=i0,i1,i2,…ik-1,使得对所有的j=0,1,2,…k-1,有xi=yi。例如X=“ABCBDAB”,Y=“BCDB”是X的一个子序列。 给定两个序列A和B,称序列Z是A和B公共子序列,是指Z同是A和B的子序列。求最长公共子序列。 若A的长度为m,B的长度为n,则A的子序列有2*m-1个,B的子序列有2*n-1个。采用枚举法分别对A和B的所以子序列一一检查,最终求出最长公共子序列。如此比较次数(2*2n)接近指数阶,当n较大时,算法太耗时,不可取。所以要全面考虑不同的情况分别进行决策,,最后通过多阶段决策逐步找出问题的最终解.当各个阶段采取决策后,会不断决策出新的数据,直到找到最优解。 二、算法设计(或算法步骤) A=”a0,a1,a2,……am-1”,B=”b0,b1,b2,……bn-1”,且Z=”z0,z1,z2……zk-1”,为她们的最长公共子序列。不难证明有一下结论: (1)如果am-1=bn-1,则zk-1=am-1=bn-1,且“z0,z1,z2,……zk-2”是“a0,a1,a2,…… am-2”和“b0,b1,b2,……bn-2”的一个最长公共子序列; (2)如果am-1!=bn-1,则若zk-1!=am-1,则“z0,z1,z2,……zk-1”是“a0,a1,a2,…… am-2”和”b0,b1,b2,……bn-1”的一个最长公共子序列。 (3)如果am-1!=bn-1,则若zk-1!=bn-1,则“z0,z1,z2,……zk-1”是“a0,a1,a2,…… am-1”和“b0,b1,b2,……bn-2”的一个最长公共子序列。 如此找到了原问题与其子问题的递归关系。 基本存储结构是存储两个字符串及其最长公共子序列的3个一位数组。当然要找出最长公共子序列,要存储当前最长公共子序列的长度和当前公共子序列的长度,而若只存储当前信息,最后只能求解最长公共子序列的长度,却不能找到最长公共子序列本身。因此需建立一个(n+1)*(m+1)的二维数组c,c[i][j]存储序列“a0,a1,a2……ai-2”和“b0,b1,……bj-1”的最长公共子序列长度,由上递推关系分析,计算c[i][j]可递归的表述如下: (1)c[i][j]=0 如果i=0或j=0;

算法设计与分析习题答案1-6章

习题1 1. 图论诞生于七桥问题。出生于瑞士的伟大数学家欧拉(Leonhard Euler ,1707—1783)提出并解决了该问题。七桥问题是这样描述的:一个人是否能在一次步行中穿越哥尼斯堡(现在 叫加里宁格勒,在波罗的海南岸)城中全部的七座桥后回到起点,且每座桥只经过一次,图是这条河以及河上的两个岛和七座桥的草图。请将该问题的数据模型抽象出来,并判断此问题是否有解。 七桥问题属于一笔画问题。 输入:一个起点 输出:相同的点 1, 一次步行 2, 经过七座桥,且每次只经历过一次 3, 回到起点 该问题无解:能一笔画的图形只有两类:一类是所有的点都是偶点。另一类是只有二个奇点的图形。 2.在欧几里德提出的欧几里德算法中(即最初的欧几里德算法)用的不是除法而是减法。请用伪代码描述这个版本的欧几里德算法 =m-n 2.循环直到r=0 m=n n=r r=m-n 图 七桥问题 南区

3 输出m 3.设计算法求数组中相差最小的两个元素(称为最接近数)的差。要求分别给出伪代码和C++描述。 编写程序,求n至少为多大时,n个“1”组成的整数能被2013整除。 #include using namespace std; int main() { double value=0; for(int n=1;n<=10000 ;++n) { value=value*10+1; if(value%2013==0) { cout<<"n至少为:"< using namespace std; int main () {

最长公共子序列问题

2.3最长公共子序列问题 和前面讲的有所区别,这个问题的不涉及走向。很经典的动态规划问题。 例题16 最长公共子序列 (lcs.pas/c/cpp) 【问题描述】 一个给定序列的子序列是在该序列中删去若干元素后得到的序列。确切地说,若给定序列X= < x1, x2,…, xm>,则另一序列Z= < z1, z2,…, zk>是X的子序列是指存在一个严格递增的下标序列< i1, i2,…, ik>,使得对于所有j=1,2,…,k有Xij=Zj 例如,序列Z=是序列X=的子序列,相应的递增下标序列为<2,3,5,7>。给定两个序列X 和Y,当另一序列Z既是X的子序列又是Y的子序列时,称Z是序列X和Y的公共子序列。例如,若X= < A, B, C, B, D, A, B>和Y= < B, D, C, A, B, A>,则序列是X和Y的一个公共子序列,序列也是X和Y的一个公共子序列。而且,后者是X和Y的一个最长公共子序列,因为X和Y没有长度大于4的公共子序列。 给定两个序列X= < x1, x2, …, xm>和Y= < y1, y2, … , yn>,要求找出X和Y的一个最长公共子序列。 【输入文件】 输入文件共有两行,每行为一个由大写字母构成的长度不超过200的字符串,表示序列X和Y。 【输出文件】 输出文件第一行为一个非负整数,表示所求得的最长公共子序列的长度,若不存在公共子序列,则输出文件仅有一行输出一个整数0,否则在输出文件的第二行输出所求得的最长公共子序列(也用一个大写字母组成的字符串表示。 【输入样例】 ABCBDAB BDCBA 【输出样例】 4 BCBA 【问题分析】 这个问题也是相当经典的。。 这个题目的阶段很不明显,所以初看这个题目没什么头绪,不像前面讲的有很明显的上一步,上一层之类的东西,只是两个字符串而且互相没什么关联。 但仔细分析发现还是有入手点的: 既然说是动态规划,那我们首先要考虑的就是怎么划分子问题,一般对于前面讲到的街道问题和数塔问题涉及走向的,考虑子问题时当然是想上一步是什么?但这个问题没有涉及走向,也没有所谓的上一步,该怎么办呢? 既然是求公共子序列,也就有第一个序列的第i个字符和第二个序列的第j个字符相等的情况。 那么我们枚第一个序列(X)的字符,和第二个序列(Y)的字符。 显然如果X[i]=Y[j]那么起点是1(下面说的子序列都是起点为1的),长度为i的子序列和长度为j的子序列的最长公共子序列就是长度为i-1和长度为j-1 的子序列中最长的公共子

数据结构--06字符串的基本操作

《数据结构》实验报告 院系光电与信息工程学院专业电子信息工程 姓名学号电话 2011级2班2013年4月22日 1.实验题目 实验6. 字符串的基本操作 2.需求分析 (1)字符串匹配。 采用顺序结构存储串,编写一个函数SubStr(str1,str2),用于判定str2是否是str1的子串。 (2)公共字符串。 问题描述编写一个函数,实现在两个已知字符串中找出所有非空最长公共子串的长度和最长公共子串的个数。 实现要求输出非空最长公共子串的长度和最长公共子串的个数。 字符串匹配: ①串长度Strlen(SString str) ②判断是否为子串SubStr(SString str1,SString str2) 公共字符串: ①串长度Strlen(SString str) ②最大公共串长度函数maxlen() ③求公共串个数函数SubStrnum() 输入形式:字符串。 3.概要设计 (1) ADT SString{ 数据对象:D={a i|a i∈IntegerSet,i=0,1,2,…,n,n≥0} 结构关系:R={|a i,a i+1 ∈D} 基本操作: Strlen(SString str) 操作前提:字符串str已存在 操作结果:求str的长度 SubStr(SString str1,SString str2) 操作前提:字符串str已存在 操作结果:判断str2是不是str1的子串 } ADT SString{ 数据对象:D={a i|a i∈IntegerSet,i=0,1,2,…,n,n≥0}

基本操作: Strlen(SString str) 操作前提:字符串str已存在 操作结果:求str的长度 maxlen(SString str1,SString str2,SString str) 操作前提:字符串str1,str2,str已存在 操作结果:求str1和str2的最大公共子串长度,并将该子串赋给str SubStrnum(SString str1,SString str2) 操作前提:字符串str1,str2已存在 操作结果:求在str1中str2子串的个数 } (2)字符串匹配: 本程序包含3个函数: ?主函数main() ?求串长函数Strlen(SString str) ?{字符串匹配函数SubStr(SString str1,SString str2) 各函数调用关系:主函数main调用其他两个函数 公共字符串: 本程序包含4个函数: ?主函数main() ?求串长函数Strlen(SString str) ?最大公共串长度函数maxlen() ?求公共串个数函数SubStrnum() 各函数调用关系:主函数main调用其他三个函数 (3)字符串匹配: 主函数的伪码 main() { 定义SString 变量str1,str2; 输入第一个字符串; 输入第二个字符串; 调用字符串匹配函数; 输出匹配结果; } 公共字符串: 主函数的伪码

最长公共子序列问题

实验三最长公共子序列问题 1.实验环境 本实验采用 java 语言编写实现,环境:,编译器: eclipse 2.实验目的 通过最长公共子序列问题,巩固并详细分析动态规划思想和解题 步骤。 3.设计思路 最长公共子序列的定义为:设有两个序列S[1..m]和9[仁n],需要寻找它们之间的一个最长公共子序列。 例如,假定有两个序列: S1: I N T H E B E G I N N I N G S2: A L L T H I N G S A R E L O S T 则S i和S的一个最长公共子序列为 THING又比如: S1: A B C B D A B S2: B D C A B A 则它们的一个最长公共子序列为 BCBA。 这里需要注意的是,一个子序列不一定必须是连续的,即中间可被其他字符分开,单它们的顺序必须是正确的。另外,最长公共子序列不一定只有一个,而我们需要寻找的是其中一个。

当然,如果要求子序列里面的元素必须连成一片也是可以的。实际上,连成一片的版本比这里实现的更容易。 4.过程 我们可以通过蛮力策略解决这个问题,步骤如下: 1.检查S1[1..m]里面每一个子序列。 2.看看其是否也是S2[1..n]里的子序列。 3.在每一步记录当前找到的子序列里面最长的子序列。 这种方法的效率十分低下。因此本实验采用动态规划的方法实现该算法。 利用动态规划寻找最长公共子序列步骤如下: 1.寻找最长公共子序列的长度。 2.扩展寻找长度的算法来获取最长公共子序列。 策略:考虑序列S1和S2的前缀序列。 设 c[i,j] = |LCS (S1[1..i],S2[1..j]),则有 c[m, n] = |LCS(S1 S2)| 所以有 c[ i -1 , j -1 ] + 1, 如要 S1[i] = S2[j] c[i, j]= max{ c [ i - 1, j ], c[ i , j -1 ] }, 如果 S1[i]工S2[j] 然后回溯输出最长公共子序列过程:

2009.1算法设计与分析课程期末试卷-A卷(含答案)

华南农业大学期末考试试卷(A卷) 2008学年第一学期考试科目:算法分析与设计 考试类型:(闭卷)考试时间:120分钟 学号姓名年级专业 一、选择题(20分,每题2分) 1.下述表达不正确的是。D A.n2/2 + 2n的渐进表达式上界函数是O(2n) B.n2/2 + 2n的渐进表达式下界函数是Ω(2n) C.logn3的渐进表达式上界函数是O(logn) D.logn3的渐进表达式下界函数是Ω(n3) 2.当输入规模为n时,算法增长率最大的是。A A.5n B.20log2n C.2n2D.3nlog3n 3.T(n)表示当输入规模为n时的算法效率,以下算法效率最优的是。C A.T(n)= T(n – 1)+1,T(1)=1 B.T(n)= 2n2 C.T(n)= T(n/2)+1,T(1)=1 D.T(n)= 3nlog2n 4.在棋盘覆盖问题中,对于2k×2k的特殊棋盘(有一个特殊方块),所需的L型骨 牌的个数是。A A.(4k– 1)/3 B.2k /3 C.4k D.2k 5.在寻找n个元素中第k小元素问题中,若使用快速排序算法思想,运用分治算法 对n个元素进行划分,应如何选择划分基准?下面答案解释最合理。D A.随机选择一个元素作为划分基准

B.取子序列的第一个元素作为划分基准 C.用中位数的中位数方法寻找划分基准 D.以上皆可行。但不同方法,算法复杂度上界可能不同 6. 现在要盖一所邮局为这9个村庄服务,请问邮局应该盖在才能使到邮局到这9个村庄的总距离和最短。C A.(4.5,0)B.(4.5,4.5)C.(5,5)D.(5,0) 7.n个人拎着水桶在一个水龙头前面排队打水,水桶有大有小,水桶必须打满水, 水流恒定。如下说法不正确?A A.让水桶大的人先打水,可以使得每个人排队时间之和最小 B.让水桶小的人先打水,可以使得每个人排队时间之和最小 C.让水桶小的人先打水,在某个确定的时间t内,可以让尽可能多的人打上水D.若要在尽可能短的时间内,n个人都打完水,按照什么顺序其实都一样 8.分治法的设计思想是将一个难以直接解决的大问题分割成规模较小的子问题,分 别解决子问题,最后将子问题的解组合起来形成原问题的解。这要求原问题和子问题。C A.问题规模相同,问题性质相同B.问题规模相同,问题性质不同 C.问题规模不同,问题性质相同D.问题规模不同,问题性质不同 9.对布线问题,以下是不正确描述。C A.布线问题的解空间是一个图 B.可以对方格阵列四周设置围墙,即增设标记的附加方格的预处理,使得算法简化对边界的判定 C.采用广度优先的标号法找到从起点到终点的布线方案(这个方案如果存在的话)不一定是最短的 D.采用先入先出的队列作为活结点表,以终点b为扩展结点或活结点队列为空作为算法结束条件 10.对于含有n个元素的子集树问题,最坏情况下其解空间的叶结点数目为。 B

最长公共子序列实验报告

最长公共子序列问题 一.实验目的: 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)的最长公共子序列相同。 如图所示:

最长公共子序列问题LCS-Read

最长公共子序列问题LCS 问题描述 一个给定序列的子序列是在该序列中删去若干元素后得到的序列。确切地说,若给定序列X=,则另一序列Z=是X的子序列是指存在一个严格递增的下标序列,使得对于所有j=1,2,…,k有 例如,序列Z=是序列X=的子序列,相应的递增下标序列为<2,3,5,7>。 给定两个序列X和Y,当另一序列Z既是X的子序列又是Y的子序列时,称Z是序列X和Y的公共子序列。例如,若X=和Y=,则序列是X和Y的一个公共子序列,序列也是X和Y的一个公共子序列。而且,后者是X和Y的一个最长公共子序列,因为X和Y没有长度大于4的公共子序列。 最长公共子序列(LCS)问题:给定两个序列X=和Y=,要求找出X和Y的一个最长公共子序列。 参考解答 动态规划算法可有效地解此问题。下面我们按照动态规划算法设计的各个步骤来设计一个解此问题的有效算法。 1.最长公共子序列的结构 解最长公共子序列问题时最容易想到的算法是穷举搜索法,即对X的每一个子序列,检查它是否也是Y的子序列,从而确定它是否为X和Y的公共子序列,并且在检查过程中选出最长的公共子序列。X的所有子序列都检查过后即可求出X和Y的最长公共子序列。X 的一个子序列相应于下标序列{1, 2, …, m}的一个子序列,因此,X共有2m个不同子序列,从而穷举搜索法需要指数时间。 事实上,最长公共子序列问题也有最优子结构性质,因为我们有如下定理: 定理: LCS的最优子结构性质 设序列X=和Y=的一个最长公共子序列Z=,则: 1.若x m=y n,则z k=x m=y n且Z k-1是X m-1和Y n-1的最长公共子序列; 2.若x m≠y n且z k≠x m ,则Z是X m-1和Y的最长公共子序列;

第4章串 作业(参考答案)

第四章串作业 参考答案: 1、简述空串和空格串(或称空格符串)的区别? 1)空串是指不包括任何字符的串,空格串指包含若干个空格字符的字符串; 2)空串长度为零,空格串长度为所包括的空格字符的个数。2、设s=‘I AM A STUDENT ’,t=‘GOOD’,q=‘WORKER’.求: 1)StrLength(s) 2)StrLength(t) 3)SubString(s,8,7) 4)SubSting(t,2,1) 5)Index(s,’A’) 6)index(s,t) 7)Replace(s,’STUDENT’,q) 8)Concat(SubString(s,6,2),Concat(t,SubString (s,7,8))) 答: 1)StrLength(s)=14 2)StrLength(t)=4 3)SubString(s,8,7) = ‘STUDENT’ 4)SubSting(t,2,1) = ‘O’ 5)Index(s,’A’)= 3

6)index(s,t) = 0 7)Replace(s,’STUDENT’,q) = ‘I AM A WORKER ’ 8)Concat(SubString(s,6,2),Concat(t,SubString(s, 7,8))) = ‘A GOOD STUDENT’ 3、若串S1=‘ABCDEFG’, S2=‘9898’ ,S3=‘###’,S4=‘012345’,执行 concat(replace(S1,substr(S1,length(S2),length(S3)),S3),subs tr(S4,index(S2,‘8’),length(S2)))其结果是多少? 答:ABC###G1234 4、下列算法实现求采用顺序结构存储的串s和串t的一个最长公共子串。请将空格处填上正确的语句。 void maxcomstr(orderstring *s,*t; int index, length) { int i,j,k,length1,con; index=0;length=0;i=1; while (i<=s.len) { j=1; while(j<=t.len) { if (s[i]= =t[j]) { k=1; length1=1; con=1; while(con) if (1) _ { length1=length1+1;k=k+1; } else (2) __; if (length1>length) { index=i; length=length1; } (3)____; } else (4) ___;

最长公共子序列问题

实验三最长公共子序列问题 1. 实验环境 本实验采用java 语言编写实现,环境:,编译器:eclipse 2. 实验目的 通过最长公共子序列问题,巩固并详细分析动态规划思想和解题步骤。 最长公共子序列的定义为:设有两个序列S i[1..m]和84仁n],需要寻找它们之间的一个最长公共子序列。 例如,假定有两个序列: 81:I N T H E B E G I N N I N G 82:A L L T H I N G 8 A R E L O 8 T 则8i和S的一个最长公共子序列为THING又比如: 81:A B C B D A B 82:B D C A B A 则它们的一个最长公共子序列为BCBA。 这里需要注意的是,一个子序列不一定必须是连续的,即中间可被其他字符分开,单它们的顺序必须是正确的。另外,最长公共子序列不一定只有一个,而我们需要寻找的是其中一个。

当然,如果要求子序列里面的元素必须连成一片也是可以的。实 际上,连成一片的版本比这里实现的更容易。 4.过程 我们可以通过蛮力策略解决这个问题,步骤如下: 1. 检查S1[1..m]里面每一个子序列。 2. 看看其是否也是S2[1..n]里的子序列。 3. 在每一步记录当前找到的子序列里面最长的子序列。 这种方法的效率十分低下。因此本实验采用动态规划的方法实现 该算法。 利用动态规划寻找最长公共子序列步骤如下: 1.寻找最长公共子序列的长度。 2.扩展寻找长度的算法来获取最长公共子序列。 策略:考虑序列S1和S2的前缀序列。 设 c[i ,j] = |LCS (S1[1..i],S2[1..j]),则有 c[m , n] = |LCS(S1 S2)| 所以有 c[i ,j]= max{ c [ i - 1, j ], c[ i , j -1 ] }, c[ i -1 , j -1 ] + 1, 如要 S1[i] = S2[j] 如果 S1[i]工 S2[j]

动态规划法求解最长公共子序列(含Java代码)

公共子序列问题徐康123183 一.算法设计 假设有两个序列X和Y,假设X和Y分别有m和n个元素,则建立一个二维数组C[(m+1)*(n+1)],记录X i与Y j的LCS的长度。将C[i,j]分为三种情况: 若i =0 或j =0时,C[i,j]=0; 若i,j>0且X[i]=Y[j],C[i,j]=C[i-1,j-1]+1; 若i,j>0且X[i] Y[j],C[i,j]=max{C[i-1,j],C[i,j-1]}。 再使用一个m*n的二维数组b,b[i,j]记录C[i,j]的来向: 若X[i]=Y[j],则B[i,j]中记入“↖”,记此时b[i,j] = 1; 若X[i] Y[j]且C[i-1,j] > C[i,j-1],则b[i,j]中记入“↑”,记此时B[i,j] = 2; 若X[i] Y[j]且C[i-1,j] < C[i,j-1],则b[i,j]中记入“←”,记此时B[i,j] = 3; 若X[i]Y[j]且C[i-1,j] = C[i,j-1],则b[i,j]中记入“↑”或“←”,记此时B[i,j] = 4; 得到了两个数组C[]和B[],设计递归输出LCS(X,Y)的算法: LCS_Output(Direction[][], X[], i, j, len,LCS[]){ If i=0 or j=0 将LCS[]保存至集合LCS_SET中 then return; If b[i,j]=1 then /*X[i]=Y[j]*/ {LCS_Output(b,X,i-1,j-1); 将X[i]保存至LCS[len-i];} else if b[i,j]=2 then /*X[i]Y[j]且C[i-1,j]>C[i,j-1]*/ LCS_Output(b,X,i-1,j) else if b[i,j]=3 then /*X[i]Y[j]且C[i-1,j]

最长公共子序列

动态规划

一、问题描述 用动态规划法求两个字符串A=‘xzyzzyx’和B=‘zxyyzxz’的最长公共子序列 二、算法分析 (1)、若xm=yn,则zk=xm=yn,且Zk-1是Xm-1和Yn-1的最长公共自序列; (2)、若xm≠yn,且zk≠xm,则Zk是Xm-1和Yn的最长公共自序列; (3)、若xm≠yn,且zk≠yn,则Zk是Xm和Yn-1的最长公共自序列;设L(m,n)表示序列X={x1,x2,…,xm}和Y={y1,y2,…,yn}的最长公共子序列的长度 L表示已经决策的长度 S表示每个决策的状态 L(0,0)=L(0,j)=0 1≤i≤m, 1≤j≤n L(i-1,j-1)+1 xi=yi,i≥1,j≥1 L(i,j)= max{L(i,j-1),(L(i-1,j)} xi≠yi,i≥1,j≥1 1 xi=yi S(i,j)= 2 xi≠yi 且L(i,j-1)≥L(i-1,j) 3 xi≠yi 且L(i,j-1)< L(i-1,j)

长度矩阵L 三、源代码 #include #include using namespace std; int main() { string str1 = "xzyzzyx"; string str2 = "zxyyzxz"; int x_len = str1.length(); int y_len = str2.length();

int arr[50][50] ={{0,0}}; int i = 0; int j = 0; for(i = 1; i <= x_len; i++) { for(j = 1; j <= y_len; j++) { if(str1[i - 1] == str2[j - 1]) { arr[i][j] = arr[i - 1][j - 1] + 1; } else if(arr[i][j - 1] >= arr[i - 1][j]) arr[i][j] = arr[i][j - 1]; else arr[i][j] = arr[i -1][j]; } } for(i = 0 ; i <= x_len; i++) {

相关文档
相关文档 最新文档