华为OJ 公共字串计算&&查找两个字符串a,b中的最长公共子串

题目描述

题目标题:

计算两个字符串的最大公共字串的长度,字符不区分大小写

详细描述:

接口说明

原型:

int getCommonStrLength(char * pFirstStr, char * pSecondStr);

输入参数:

     char * pFirstStr //第一个字符串

     char * pSecondStr//第二个字符串

 


输入描述:
 
   

输入两个字符串



输出描述:
 
   

输出一个整数


输入例子:
asdfas werasdfaswer

输出例子:

6

分析:

最长公共子字符串必须是连续的。如果我们使用递归的方法解决的话,对于每一对字符就需要判断前面的是否已构成字串,这就会使子问题出现重复计算的问题。对于重复子问题,还是要使用动态规划的思想。

假设需要求的字符串为 str1 , str2 .函数 f(m,n) 求分别以str1[m] , str2[n] 结尾的公共字符串长度。
这有一下递推公式:

f(m,n)=0        str1[m] != str2[n] ;
f(m,n)=f(m-1,n-1) + 1      str[m]==str2[n];

别忘了递推的特殊边界:
f(0,n)=0;
f(m,0)=0;

牛客通过 华为OJ 只得223分 先这样代码如下

#include  
#include 
using namespace std;
void func(string str1, string str2)
{	int length1 = str1.size();
	int length2 = str2.size();
	int **c = new int*[length1];
	for (int i = 0; i < length1;i++)
	{
		c[i] = new int[length2];
	}
	for (int i = 0; icount) { count = c[i][j]; besti = i; bestj = j; }   //查找最长子字符串  

	cout << count << endl;//之后为输出公共字串,题目没要求
	/*if (count == 0) cout << endl;  //公共子字符串长度为1,输出空行  
	else
	for (int i = besti - count + 1; i <= besti; i++) cout << str1[i];   //否则输出靠X左边(如果多个)子字符串  
	*/
}

int main()
{
	string s1,s2;
	while (cin>>s1>>s2)
	{
		func(s1,s2);
	}
	return 0;
}

题目描述

查找两个字符串a,b中的最长公共子串。若有多个,输出在较短串中最先出现的那个。 
输入描述:
输入两个字符串


输出描述:
返回重复出现的字符

输入例子:
abcdefghijklmnop
abcsafjklmnopqrstuvw

输出例子:
jklmnop
这道题要求输出公共子串 若有多个,则输出在较短串中最先出现的那个。还采用上述方法,只不过先分出长短字符串,每次按照短字符串输出即可
代码如下
#include
#include
using namespace std;
int main()
{
	string s1, s2;
    
	while (getline(cin, s1))
	{

		getline(cin, s2);
		string l = (s1.size() > s2.size() ? s1 : s2);
		string s = (s1.size() > s2.size() ? s2 : s1);
		int m = s.size();//短字符串的长度
		int n = l.size();//长字符串的长度
		int** c = new int*[m];
		for (int i = 0; i < m; i++)
		{
			c[i] = new int[n];
		}
		for (int i = 0; i < m; i++)
		for (int j = 0; j < n; j++)
		{
			c[i][j] = 0;
		}
		for (int i = 0; i < m; i++)
		for (int j = 0; j < n; j++)
		{
			if (s[i] == l[j])
			{
				if (i == 0 || j == 0)c[i][j] = 1;
				else c[i][j] = c[i - 1][j - 1] + 1;
			}
			else
				c[i][j] = 0;
		}
		int count = 0;
		int besti = 0;
		for (int i = 0; i < m; i++)//找出最长的字符串大小
		for (int j = 0; j < n; j++)
		{
			if (c[i][j]>count)
			{
				count = c[i][j];
				besti = i;
			}
		}
		bool find = false;//找寻最短字符串中公共字符串第一次出现的下标(如果只出现一次找到即可;出现多次找到的是第一次出现的下标)
                             for (int i = 0; i 




你可能感兴趣的:(算法学习,dp)