当前位置:首页 » 公共卫生 » 公共子序列

公共子序列

发布时间: 2020-11-24 03:29:28

『壹』 求公共子序列程序题,求大神指导

看不懂t=j+1的用意制。

我觉得,最核心的代码是检查b中从r开始是否和a中从t开始有一个子序列相同,所以是for(r=0;r<n;r++)嵌套for(t=0;t<m,t++)如下。i、j控制比较这没问题,下面我给和为一个变量了。

for(r=0;r<n;++r)
for(t=0;t<m;++t)
{
sum=0;
for(i=0;r+i<n&&t+i<m&&b[r+i]==a[t+i];++i)
++sum;
if(sum>x)
x=sum;
}

『贰』 求最长公共子序列(动态规划)

// 求LCS的长度
class LCS
{
public:
LCS(int nx, int ny, char *x, char*y); //创建二维数组c、s和一维数组a、b,并进行初始化
void LCSLength(); //求最优解值(最长公共子序列长度)
void CLCS(); //构造最优解(最长公共子序列)
……
private:
void CLCS(int i, int j);
int **c, **s.m, n;
char *a, *b;
};
int LCS::LCSLength()

{
for(int i=1; i<=m; i++) c[i][0]=0;
for(i=1; i<=n; i++) c[0][i]=0;
for (i=1; i<=m; i++)
for (int j=1; j<=n; j++)
if (x[i]==y[j]){
c[i][j]=c[i-1][j-1]+1; s[i][j]=1; //由c[i-1][j-1]计算c[i][j]
}
else if (c[i-1][j]>=c[i][j-1]){
c[i][j]=c[i-1][j]; s[i][j]=2; //由c[i-1][j]得到c[i][j]
}
else {
c[i][j]=c[i][j-1]; s[i][j]=3; //由c[i][j-1]得到c[i][j]
}
return c[m][n]; //返回最优解值
}

// 构造最长公共子序列
void LCS::CLCS(int i, int j)
{
if (i==0||j==0) return;
if (s[i][j]==1){
CLCS(i-1, j-1);
cout<<a[i];
}
else if (s[i][j]==2) CLCS(i-1, j);
else CLCS(i, j-1);
}

『叁』 最长公共子序列的c++代码实现

//最大公共子序列

#include<iostream>
#include<string>
using namespace std;

void LCSLength(int m, int n, string &x, string &y,int ** c, int **b)
{
int i,j;
for( i=1;i<=m;i++) c[i][0]=0;
for( i=1;i<=n;i++) c[0][i]=0;
cout<<"111"<<endl;
for( i=1;i<=m;i++)
for( j=1;j<=n;j++)
{
if( x[i-1]==y[j-1] )
{
c[i][j] = c[i-1][j-1]+1;
b[i][j]=1;
}
else
{
if( c[i-1][j] >= c[i][j-1] )
{
c[i][j] = c[i-1][j];
b[i][j]=2;
}
else
{
c[i][j] = c[i][j-1];
b[i][j]=3;
}
}

}
}

void LCS(int i, int j, string& x, int **b, string &result)
{
if(i==0 || j==0) return;
if(b[i][j] == 1)
{
LCS(i-1,j-1,x,b,result);
result+=x[i-1];
}
else
{
if(b[i][j] == 2)
LCS(i-1,j,x,b,result);
else
LCS(i,j-1,x,b,result);
}
}

string dp(string &x,string &y,string & result)
{
int m=x.size();
int n=y.size();

int **c=new int*[m+1];
for(int i=0;i<=m;i++)
c[i]=new int[n+1];

int **b=new int*[m+1];
for(int i=0;i<=m;i++)
b[i]=new int[n+1];

c[0][0]=0;
LCSLength(m, n, x, y, c, b);

LCS(m, n, x, b, result);
return result;

}

int main()
{
//
string x="find";

string y="fnid";
string result="";
dp(x,y,result);

cout<<x<<endl;
cout<<y<<endl;
cout<<result<<endl;
return 1;
}

『肆』 求最长公共子序列的C语言程序

得到字符串m1,m2后,有一个为空则子列为空。

如果都不为空,开始下面的步骤。

求得两列的长度分别为n1,n2。

动态生n2行n1列矩阵(二维数组)。

取m2中每个元素(记位置为i)与m1中元素(记位置为j)逐个比较,如果相等则为矩阵中相应行列坐标的元素赋值为1,否则为0(可用循环嵌套完成)。

比如m1(abc0cbad)m2(cba1abc)两串的话,可以得到如图所示矩阵。

然后,不难看出,要进行如下步骤。

定义max,用来记录最大子列中元素个数。

定义数组l[n2],用来记录最大子列的首字符地址(因为可能有不同最大子列,故用数组,而不是单个变量)。

判断矩阵中每一个元素,是否为1,如果是则记下此时行地址到l数组,然后判断相对于这个元素的下一行下一列的元素是否为1,如果是则继续判断,一直到为0。记下此次判断(即一个while循环)中“1”的个数n,存入变量max。

对于矩阵中的每一个元素都这么判断,如果判断中n的值大于max那么把n付给max,同时把这个子列的首地址付给l[0],l[0]后面的元素全赋值为-1。如果,某次判断得到的n与max相同,即有相同最大子列,那么把它的首地址存入l数组的下一个位置。

当这个矩阵的每一个元素都判断完毕后,会得到max,和数组l,然后用循环做如下输出过程:依次以l数组中的每个元素为首地址,输出m2字符串中以相应序号开头的max个字符,那么完成所有最大子列的输出。

昨天失眠了,一直到今天凌晨3点多,脑袋浑浑噩噩的,本想帮你敲代码,可是脑力不支了,估计敲出来也乱,还有问题的话,再讨论452032545

『伍』 Pascal 最长公共子序列

varn,i,j:longint;
a,b,numa,numb:array[1..100000]oflongint;

procereqsrta(h,t:longint);
vari,j,k,x,y:longint;
begin
ifh>=tthenexit;
k:=random(t-h+1)+h;
x:=a[k];a[k]:=a[h];a[h]:=x;
y:=numa[k];numa[k]:=numa[h];numa[h]:=y;
i:=h;j:=t;
whilei<jdobegin
while(i<j)and(a[j]>x)dodec(j);
ifi<jthenbegina[i]:=a[j];numa[i]:=numa[j];inc(i);end;
while(i<j)and(a[i]<x)doinc(i);
ifi<jthenbegina[j]:=a[i];numa[j]:=numa[i];dec(j);end;
end;
a[i]:=x;numa[i]:=y;
qsrta(h,i-1);qsrta(i+1,t);
end;

procereqsrtb(h,t:longint);
vari,j,k,x,y:longint;
begin
ifh>=tthenexit;
k:=random(t-h+1)+h;
x:=b[k];b[k]:=b[h];b[h]:=x;
y:=numb[k];numb[k]:=numb[h];numb[h]:=y;
i:=h;j:=t;
whilei<jdobegin
while(i<j)and(b[j]>x)dodec(j);
ifi<jthenbeginb[i]:=b[j];numb[i]:=numb[j];inc(i);end;
while(i<j)and(b[i]<x)doinc(i);
ifi<jthenbeginb[j]:=b[i];numb[j]:=numb[i];dec(j);end;
end;
b[i]:=x;numb[i]:=y;
qsrtb(h,i-1);qsrtb(i+1,t);
end;

procereqsrtnumab(h,t:longint);
vari,j,k,x,y:longint;
begin
ifh>=tthenexit;
k:=random(t-h+1)+h;
x:=numa[k];numa[k]:=numa[h];numa[h]:=x;
y:=numb[k];numb[k]:=numb[h];numb[h]:=y;
i:=h;j:=t;
whilei<jdobegin
while(i<j)and(numa[j]>x)dodec(j);
ifi<jthenbeginnuma[i]:=numa[j];numb[i]:=numb[j];inc(i);end;
while(i<j)and(numa[i]<x)doinc(i);
ifi<jthenbeginnuma[j]:=numa[i];numb[j]:=numb[i];dec(j);end;
end;
numa[i]:=x;numb[i]:=y;
qsrtnumab(h,i-1);qsrtnumab(i+1,t);
end;

functionbfind(h,t,x:longint):longint;
varm:longint;
begin
ifh>tthenbfind:=h
elsebegin
m:=(h+t)div2;
ifx<numa[m]thenbfind:=bfind(h,m-1,x)
elsebfind:=bfind(m+1,t,x);
end;
end;

begin
randomize;
assign(input,'LCS.IN');reset(input);
assign(output,'LCS.OUT');rewrite(output);
read(n);
fori:=1tondoread(a[i]);
fori:=1tondoread(b[i]);
fori:=1tondobeginnuma[i]:=i;numb[i]:=i;end;
qsrta(1,n);
qsrtb(1,n);
qsrtnumab(1,n);
fori:=1tondonuma[i]:=maxlongint;
fori:=1tondobegin
j:=bfind(1,n,numb[i]);
numa[j]:=numb[i];
end;
j:=bfind(1,n,maxlongint-1);
writeln(j-1);
close(output);close(input);
end.

『陆』 最长公共子串和最长公共子序列的区别

/* 目标:输出两个字符串的所有公共最长子序列
date: 09-11-26
BY: zggxjxcgx
算法: 判断较短串是否为较长串的子序列,如果是则得到结果;
否则,对较短串进行逐个字符删除操作(将字符替换为'#'表示删除)。
删除操作用递归函数进行实现。每层递归删除一个字符,
若删除一个字符后未得到匹配子序列,则还原该字符所在位置。
第n层递归未找到匹配子序列,则将递归层数加1,重复删除直到剩下空串。

*/
#include<stdio.h>
#include<string.h>
int dep=0; /* 较短串的长度 */
int depflag=0; /*下一步要探测的深度 */
int lastflag=0; /* 是否找到匹配子序列,1为找到 */
int count=0; /* 目标结果的个数 */

int mystrcmp(char *s1,char *s2) /* 判断s2是否为 s1的子串 */
{ while(*s1 *s2)
if(*s2=='#') s2++;
else if(*s2 == *s1) { s1++; s2++; }
else s1++;

while(*s2=='#') s2++;
if(*s2=='\0') return 1;
return 0;
}
void pristr(char *str) /* 打印最长子序列 */
{ if(0==count++) printf("\n公共最长子序列:\n");
printf("%2d:",count);
while(*str)
{ if(*str!='#')
printf("%c",*str);
str++;
}
printf("\n");
}

/*递归函数求最长子序列。start 控制下一个要检测的字符,deptemp控制递归的深度,first为's'表示第一层递归 */
int fun(char *str1,char *str2,char *start,int deptemp,char first)
{ int i=0,j=0;
char *s,cback;
do
{ s=start;
if('s'==first) deptemp=depflag; /* 在第一层设置递归深度 */
while(*s)
{ if(*s=='#') { s++; continue; }
cback=*s; *s='#'; /* 删除当前字符*/
if(mystrcmp(str1,str2)) { pristr(str2); lastflag=1; } /*找到匹配,将lastflag设为1,在完成深度为deptemp+1的探测(找到所有匹配)后退出递归 */
else if(deptemp>0) fun(str1,str2,s+1,deptemp-1,'n'); /* 深度探测,s+1表示从下一个位置开始删除 */
*s=cback; s++; /* 还原该位置的字符,以便下次进行探测 */
}
if('s'==first) ++depflag; /* 删除depflag+1个字符还未找到,则递归深度加1 */
}while(depflag<dep-1 's'==first 0==lastflag); /* 第一层递归具有特殊意义,由三个变量标记是否第一层 */
if(lastflag) return 1; /* lastflag 为1 表示找到匹配子序列 */
return 0;
}
void main()
{ char *s1,*s2;
char st1[]="asfdebjewcwedwk";
char st2[]="sabscdkwss"; // kwfsa
if(strlen(st1)>strlen(st2)) s1=st1,s2=st2; /* 将s1设为较长的串 */
else s1=st2,s2=st1;

printf("\nstr1:%s\nstr2:%s\n",s1,s2);
dep=strlen(s2); /* 得到较短串的长度 */
if(mystrcmp(s1,s2)) pristr(s2);
else if(0==fun(s1,s2,s2,0,'s')) printf("\n没有公共元素!\n");
// printf("%d\n",mystrcmp("afdebjewcwedw","abcdw#"));
}

『柒』 最长公共子串和最长公共子序列的区别。举个例子不要写代码。

应该是这样:
字符串1:abcde
字符串2:abcdfe
那么:
最长公共子串:abcd
最长公共子序列:abcde
就是公共子串,必须在待匹配字符串中连续,而公共子序列只需要相对顺序匹配就行。
前者一般用KMP算法,后者一般用动态规划解决吧。

『捌』 求数组的最大子数组值和最长公共子序列问题

a) 最长公共子序列的结构
若用穷举搜索法,耗时太长,算法需要指数时间。
易证最长公共子序列问题也有最优子结构性质
设序列X=<x1, x2, …, xm>和Y=<y1, y2, …, yn>的一个最长公共子序列Z=<z1, z2, …, zk>,则:
i. 若xm=yn,则zk=xm=yn且Zk-1是Xm-1和Yn-1的最长公共子序列;
ii. 若xm≠yn且zk≠xm ,则Z是Xm-1和Y的最长公共子序列;
iii. 若xm≠yn且zk≠yn ,则Z是X和Yn-1的最长公共子序列。
其中Xm-1=<x1, x2, …, xm-1>,Yn-1=<y1, y2, …, yn-1>,Zk-1=<z1, z2, …, zk-1>。
最长公共子序列问题具有最优子结构性质。

『玖』 (算法 c++)动态规划法求解最长公共子序列 本人菜鸟求高手改错帮忙完成 谢谢了

不是我不想帮你,但如果真要改的话,整个程序差不多要重写了……首先你要确定此程序是上网刷题/比赛?还是自学算法知识?如果你有很好的数学功底还可以自学知识,但比赛的话自学是绝对不够的,那需要充分的交流,还有,养成良好的编程风格是一个极其重要的方面,在网上应该可以找到某些大牛的代码集,运气好还有注释版的,可以多多借鉴。下面是一段代码,NetBeans/G++编译通过,你可以尝试改成类结构的。^_^

#include <iostream>

using namespace std;

#define MAXLENGTH 20

// 这是偷懒的部分……不要介意哈
int maxLength[MAXLENGTH + 2][MAXLENGTH + 2];
int preChar[MAXLENGTH + 2][MAXLENGTH + 2];

/*
* 参数说明
* s1:待处理字符串1
* s2:待处理字符串2
* l1:s1长度(不包括字符串结束符'/0')
* l2:s2长度(不包括字符串结束符'/0')
*
* 参数中加const的目的是为了保护外部数据,防止因失误而在函数内部改变了本因无需改变的数值。
*/
int LCSLength(const char* s1, const int l1, const char* s2, const int l2) {

/* 尽量不要在for等语句中定义变量,每个函数一开始最好就把需要的变量全部定义好,同时尽量赋予有意义的函数名 */
/* 当然,有时偷点懒是可以的,但你要确保过了几个月后一看到代码就能很快知道这是啥意思 */
int i, j;
/* maxLength用于存放中间数据,意义:maxLength[i][j]表示:s1前i个字符与s2前j个字符的最长子序列长度
* preChar用于存放当前最长子序列是由那一个自序列得来的
* 因本算法特殊性,需要各额外2位的存储空间
*/

/**/
for (i = 0; i <= l1; i++) maxLength[i][0] = 0;
for (j = 0; j <= l2; j++) maxLength[0][j] = 0;
for (i = 0; i <= l1; i++)
for (j = 0; j <= l2; j++) {
/* 如果s1第i个字符与s2第j个字符相同,则更新maxLength[i+1][j+1]存储的最大值,和preChar存放的前缀自序列位置
* 下同
*/
if (s1[i] == s2[j] && maxLength[i + 1][j + 1] < maxLength[i][j] + 1) {
maxLength[i + 1][j + 1] = maxLength[i][j] + 1;
preChar[i + 1][j + 1] = 1;
}
if (maxLength[i + 1][j] < maxLength[i][j]) {
maxLength[i + 1][j] = maxLength[i][j];
preChar[i + 1][j] = 2;
}
if (maxLength[i][j + 1] < maxLength[i][j]) {
maxLength[i][j + 1] = maxLength[i][j];
preChar[i][j + 1] = 3;
}
}

/* 返回最长子序列长度 */
return maxLength[l1][l2];
}

/**
* s1、s2与上同
* i:s1当前字符序号
* j:s2当前字符序号
*
* i、j初始值为各自字符串长度
*/
void LCSOutput(const char* s1, const int i, const char* s2, const int j) {

if (i >= 0 && j >= 0) {

// 由于是逆向输出,所以先递归,后输出
switch (preChar[i][j]) {
case 1:
LCSOutput(s1, i - 1, s2, j - 1);
break;
case 2:
LCSOutput(s1, i - 1, s2, j);
break;
case 3:
LCSOutput(s1, i, s2, j - 1);
break;
default:
break;
}

if (s1[i] == s2[j])
cout << s1[i];
}
}

int main() {

cout << "最长公共子序列长度:" << LCSLength("1234567890", 10, "1358967", 7) << endl;

cout << "最长公共子序列(不确保唯一):";
LCSOutput("1234567890", 10, "1358967", 7);
cout << endl;

return 0;
}

『拾』 求两个数列的所有公共子序列。。

先判断出两个数列的元素个数谁少
再逐个判断元素个数少的那个数列中的每一个元素是否是另一个当中的元素,从而得到最长公共子序列
最后,从最长公共子序列中循环列出所有公共子序列.

热点内容
影视转载限制分钟 发布:2024-08-19 09:13:14 浏览:319
韩国电影伤口上纹身找心里辅导 发布:2024-08-19 09:07:27 浏览:156
韩国电影集合3小时 发布:2024-08-19 08:36:11 浏览:783
有母乳场景的电影 发布:2024-08-19 08:32:55 浏览:451
我准备再看一场电影英语 发布:2024-08-19 08:14:08 浏览:996
奥迪a8电影叫什么三个女救人 发布:2024-08-19 07:56:14 浏览:513
邱淑芬风月片全部 发布:2024-08-19 07:53:22 浏览:341
善良妈妈的朋友李采潭 发布:2024-08-19 07:33:09 浏览:760
哪里还可以看查理九世 发布:2024-08-19 07:29:07 浏览:143
看电影需要多少帧数 发布:2024-08-19 07:23:14 浏览:121