【算法设计-最长公共子串与最长公共子序列】
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;
}
公共子串:一定要是字符串中连续的字符
公共子序列:可以不是联系的字符串
一.最长公共子串问题
#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;
}
相关文章推荐
- Opencv HOG行人检测 源码分析(一) 图画的很好看
- ZooKeeper - O'Reilly Media ----Zookeeper Internals (3)
- 正反斜杠的匹配
- JQuery(二)——简单动画效果
- at org.apache.coyote.http11.AbstractOutputBuffer.checkLengthBeforeWrite
- 黑马程序员----Java反射
- 模拟POST请求
- 挖掘关键词
- NSDate-管理日期和时间1
- Ubuntu 14.04配置Android编译环境
- LA 3644(并查集)
- Android ContentProvider使用样例
- [Err] ORA-00600: 内部错误代码, 参数: [qctcte1], [0], [], [], [], [], [], [], [], [], [], []
- Linux日志更改 logtamper
- navicat for mysql 10.1.7注册码
- 开源项目SwipeMenuListView学习笔记
- [LeedCode OJ]#219 Contains Duplicate II
- iOS:让UIView覆盖导航栏
- 要善待员工,但别总是太友好
- ssma for oracle