华为OJ(最长公共子串及公共最长子序列)

先说直观的方法,先给出链接:http://blog.csdn.net/xpyimapingchuan/article/details/46822645

直接上代码,很好懂,不多说了。

方案1:

#include 
#include 
using namespace std;
int main()
{
      string str1,str2;
      getline(cin,str1);
      getline(cin,str2);
      char *s;
      int num=0;
      int max_len=0;
      int start,start1,start2;
      for(int i=0;i
提交后测试用例未全部通过,只有109分,什么鬼?哪里出问题了 不晓得

方案2:使用动态规划,详细讲解在这里:http://blog.csdn.net/hackbuteer1/article/details/6686931

#include
using namespace std;
#define N 1000
int getCommonStrLength(char*,char*);
int main()
{
	char pFirstStr[N],pSecondStr[N];
	gets(pFirstStr);
	gets(pSecondStr);
	cout<num)
			{
				num=cnt[i][j];
				indexf=i-1;
				indexs=j-1;
			}
		}
		/*int k=num;
		char s[100];
		s[k--]='\0';
		while(indexf>=0&&indexs>=0)
		{
			if(pf[indexf]==ps[indexs])
			{
				s[k]=pf[indexf];
				--k;
				--indexf;
				--indexs;
			}
			else
				break;
		}
		puts(s);*/
		for(int i=0;i
提交后还是测试用例未全部通过,113分。又是什么鬼?不知道系统什么打分标准,难道是复杂度之类的?

不死心,于是搜来下面这一份,提交后223分,哇!高了很多,然并卵。还是未全部通过。不知道正确代码肿么写。

#include 
#include 
#include 
#include 
using namespace std;

int getLCStringLength(string s1, string s2)
{
    if(s1 == "" || s2 == "")
        return 0;

    int m = s1.size();
    int n = s2.size();
    vector > table(m+1, vector(n+1));

    int biggest = 0;  // 记录表中最大值
    for(int i=0; i biggest)
                    biggest = table[i][j];
            }

            else  // 不相等置0
                table[i][j] = 0;  
        }  
    }
    return biggest;
}

int main ()
{
    string input, s1, s2;
    getline(cin, input);
    stringstream ss(input);
    ss >> s1;
    ss >> s2;
    cout << getLCStringLength(s1, s2) << endl;

    return 0;
}
既然是用的别人的,给出链接:http://blog.csdn.net/lisonglisonglisong/article/details/45218665

这是别人刷的2011年的OJ,但估计也木有全部通过吧。




主要是通过这道题初步了解了动态规划解决最长公共子串(Longest Common Substirng)和最长公共子序列(Longest Common Subsequence,LCS)问题

动态规划求解最大公共字符串问题见方案2

下面对最大公共子序列详细说明以备忘:

1、序列str1和序列str2 
  ·长度分别为m+1和n+1;
  ·创建1个二维数组L[m+1,n+1];
    ·初始化L数组0行0列内容为0
    ·m和n分别从0开始,m++,n++循环:
       - 如果str1[m] == str2[n],则L[m,n] = L[m - 1, n -1] + 1;
       - 如果str1[m] != str2[n],则L[m,n] = max{L[m,n - 1],L[m - 1, n]}
    ·最后从L[m,n]中的数字一定是最大的,且这个数字就是最长公共子序列的长度
    ·从数组L中找出一个最长的公共子序列

   2、从数组L中查找一个最长的公共子序列

   i和j分别从m,n开始,递减循环直到i = 0,j = 0。其中,m和n分别为两个串的长度。
  ·如果str1[i] == str2[j],则将str[i]字符插入到子序列内,i--,j--;
  ·如果str1[i] != str[j],则比较L[i,j-1]与L[i-1,j],L[i,j-1]大,则j--,否则i--;(如果相等,则任选一个)

直接在方案2基础上稍作改动即可:
#include
using namespace std;
#define N 1000
int getCommonStrLength(char*,char*);
int main()
{
	char pFirstStr[N],pSecondStr[N];
	gets(pFirstStr);
	gets(pSecondStr);
	cout<cnt[i-1][j])
						cnt[i][j]=cnt[i][j-1];
					else
						cnt[i][j]=cnt[i-1][j];
				}
			if(cnt[i][j]>max_len)
				{
					max_len=cnt[i][j];
					indexf=i;
					indexs=j;
				}
		}
		int k=max_len;		
		char s[1000];
		s[k--]='\0';
		while(indexf>=0&&indexs>=0)
		{
			if(pf[indexf-1]==ps[indexs-1])
			{
				s[k]=pf[indexf-1];
				--k;
				--indexf;
				--indexs;
			}
			else
			{
				if(cnt[indexf][indexs-1]>cnt[indexf-1][indexs])
					--indexs;
				else
					--indexf;
			}
		}
		puts(s);
		for(int i=0;i



你可能感兴趣的:(华为OJ初级)