您的位置:首页 > 其它

【算法设计-最长公共子串与最长公共子序列】

2015-08-24 15:31 302 查看
先写代码,然后晚上上传过程图

公共子串:一定要是字符串中连续的字符

公共子序列:可以不是联系的字符串

一.最长公共子串问题

#include<iostream>

#include<vector>

#include<stack>

using namespace std;

void func(char str1[], char str2[])

{

int str1len = strlen(str1);

int str2len = strlen(str2);

vector<vector<int>>dp(str1len + 1, vector<int>(str2len + 1, 0));

int max = dp[0][0];

int tempi = 0;

int tempj = 0;

for (int i = 1; i <= str1len; i++)

{

for (int j = 1; j <= str2len; j++)

{

if (str1[i - 1] == str2[j - 1])

{

dp[i][j] = dp[i - 1][j - 1] + 1;

}

else

dp[i][j] = 0;

if (dp[i][j]>max)

{

max = dp[i][j];

tempi = i;

tempj = j;

}

}

}

cout << "最长子串长度是" << max << endl;

int i = tempi;

int j = tempj;

stack<char>charstack;

for (; dp[i][j] != 0; --i, --j)charstack.push(str1[i]);

cout << "最长公共字符串是";

while (!charstack.empty())

{

cout << charstack.top();

charstack.pop();

}

cout << endl;

}

int main(void)

{

char a[] = "edkf";

char b[] = "dk";

func(a, b);

}

二.最长公共子序列问题

#include<iostream>

#include<vector>

#include<stack>

using namespace std;

int LongestSubStr(char *str1, char *str2)

{

int i, j;

int maxi, maxj;

int n = strlen(str1);

int m = strlen(str2);

vector<vector<int>> c(n+1,vector<int>(m+1, 0));

int max = -1;

for (i = 1; i <= n; i++)

{

for (j = 1; j <= m; j++)

{

if (str1[i - 1] == str2[j - 1])

c[i][j] = c[i - 1][j - 1] + 1;

else c[i][j] = (c[i - 1][j] > c[i][j - 1]) ? c[i - 1][j] : c[i][j - 1];

if (c[i][j] >= max)

max = c[i][j];

}

}

printf("最长子序列长度是%d", max);

stack<char>a;

for (i = n, j = m; i >= 1 && j >= 1;)

{

if (str1[i - 1] == str2[j - 1])

{

a.push(str1[i - 1]);

i--;

j--;

}

else

{

if (c[i - 1][j] > c[i][j - 1])

i--;

else

j--;

}

}

cout << "子序列是:";

while (!a.empty())

{

char temp = a.top();

cout << temp;

a.pop();

}

cout << endl;

return max;

}

int main(void)

{

int max;

char a[100] = "feilong44";

char b[100] = "flng5";

max = LongestSubStr(a, b);

return 0;

}

第三题

给定一格M*N的地图,有个机器人放在左上角的格子里面,它要走到地图的右下角,这个机器人每次只能向下或者向右移动一格,当它移动到右下角时表示结束。求:有多少条不同的路径可以到达右下角?

方法:

动态规划

m==0或者n==0时候的值要设置为1,即第一行和第一列的值都要设置为1.dp[i][j]=dp[i][j-1]+dp[j][i-1];

即每个格子的值为他的上面和左边的数值的和。

代码:

#include<iostream>

#include<vector>

using namespace std;

int func(int m, int n)

{

vector<vector<int>>a(m, vector<int>(n,1));

for (int i = 1; i < m; i++)

{

for (int j = 1; j < n; j++)

a[i][j] = a[i][j - 1] + a[i - 1][j];

}

return a[m - 1][n - 1];

}

int main(void)

{

int temp=func(3, 4);

cout << temp << endl;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: