Can I fly high in the Sky?

Never say never.

导航

[华为oj]公共子串计算

Posted on 2015-09-08 22:25  lsr_flying  阅读(546)  评论(0编辑  收藏  举报

照旧,先上下我的暴力破解法:

#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

string ToLower(string ss)
{
    string::iterator itr;
    for(itr=ss.begin();itr!=ss.end();itr++)
    {
        *itr=tolower(*itr);
    }
    return ss;
}

int getCommonStrLength(string pFirstStr,string pSecondStr)
{
    int firstLen=pFirstStr.length();
    int secondLen=pSecondStr.length();
    int countMax=0;

    for(int f=0;f<firstLen;f++)
    {
        int fCurrent=f;
        for(int s=0;s<secondLen;s++)
        {
            int tempCount=0;
            int sCurrent=s;
            while(sCurrent<secondLen&&fCurrent<firstLen&&pFirstStr[fCurrent]==pSecondStr[sCurrent])
            {
                ++tempCount;
                ++fCurrent;
                ++sCurrent;
            }
            if(tempCount>countMax)
                countMax=tempCount;
        }
    }

    return countMax;
}

int main()
{
    string fStr;
    string sStr;
    cin>>fStr>>sStr;
    fStr=ToLower(fStr);
    sStr=ToLower(sStr);
    cout<<getCommonStrLength(fStr,sStr)<<endl;
}

 

两个for循环是必须的,但是第二层的for循环内的while就明显是进行了很多重复的操作比较。得改!那就是要记录之前做过的记录,考虑用动态规划思想进行。

其实我开始的时候打算用后缀数组进行比较,但没思路。就没进行下去了。最后,在网上搜了下,有一种思路是利用前缀数组进行LCS算法。用一个二维数组Sub[firstLen][SecondLen]记录公共字符串,即Sub[m][n]记录的是第一个字符串第m位开始于第二个字符串第n位开始具有的公共字符串。那么,在比较Sub[m+1][n+1]时,我们只需要判断FirstStr[m+1],SecondStr[n+1]即可,如果他们相同,那么就可以利用之前Sub[m][n]的记录,因为第一个字符串从m+1往前,m位以前的之前已经比较过了;同理,第二个字符串从n+1开始,n位之前的已经比较过了,所以Sub[m+1][n+1]=Sub[m][n]+FirstStr[m+1]。

 

代码:

http://blog.csdn.net/liufeng_king/article/details/8528858

// CPPPRO.cpp : 定义控制台应用程序的入口点。  
//3m6 最长公共子串,动态规划实现  
#include "stdafx.h"  
#include <iostream>    
#include <string>  
using namespace std;   
  
string getLCSLength(string &s, string &t);  
  
int main()  
{  
    string s,t;  
    cout<<"请输入字符串s:"<<endl;  
    cin>>s;  
    cout<<"请输入字符串t:"<<endl;  
    cin>>t;  
    cout<<"最长公共子串为:"<<endl;  
    cout<<getLCSLength(s,t)<<endl;  
    return 0;  
}  
  
string getLCSLength(string &s, string &t)  
{  
    int p = s.length();  
    int q = t.length();  
  
    string **num = new string *[p];    
    for(int i=0;i<p;i++)      
    {      
        num[i] = new string[q];    
    }     
  
    char char1 = '\0';  
    char char2 = '\0';  
  
    int len = 0;  
    string lcs = "" ;  
  
    for(int i=0; i<p; i++)  
    {  
        for (int j=0; j<t.length(); j++)  
        {  
            char1 = s.at(i);  
            char2 = t.at(j);  
            if(char1!=char2)  
            {  
                num[i][j] = "" ;  
            }  
            else  
            {  
                if (i==0||j==0)  
                {  
                    num[i][j]=char1;  
                }  
                else  
                {  
                    num[i][j]=num[i-1][j-1]+char1;  
                }  
                if(num[i][j].length()>len)  
                {  
                    len = num[i][j].length() ;  
                    lcs = num[i][j];  
                }  
                else if(num[i][j].length()==len)  
                {  
                    lcs = lcs + "," + num[i][j];  
                }  
            }  
        }  
    }  
  
    for(int i=0;i<p;i++)      
    {      
        delete[] num[i];   
    }   
    delete[] num;  
  
    return lcs;  
}