華為 oj 公共子串計算
水題,原來以為用dp陣列 結果wrong了兩次 我想還是自己小題大做了···呵呵··
獻給初學者作為參考
#include <stdio.h> #include <string.h> #define MAX 200 int getCommonStrLength(char * pFirstStr, char * pSecondStr) { int m = strlen(pFirstStr); int n = strlen(pSecondStr); int max = 0; int number = 0; if(pFirstStr==NULL||pSecondStr==NULL) { return 0; } for( int i = 0;i < m;i ++) { for(int j = 0;j < n;j ++) { if(i==m||j==n){break;} while(pFirstStr[i] == pSecondStr[j]) { i++; j++; number++; } if(max < number) { max = number; } if(i==m||j==n){break;} } } return max; } int main(void) { char s1[200] = { "\0" }; char s2[200]= { "\0" }; scanf("%s",s1); scanf("%s",s2); int num = getCommonStrLength(s1,s2); printf("%d\n",num); return 0; }
==========================================
最長公共子串是常見的面試題
出現困惑的是讀者對
最長公共子串
最長公共子序列產生混淆
二者的區別是
最長公共子串 要求子串中的單個字元必須都是連續的
最長公共子序列 要求 去掉一部分元素 只要滿足 序列中部分的元素 符合某種規律即可
他們處理辦法的核心都是一致的
----------------------------------引用自某大神參加面試的總結
子序列跟子串的求法類似,都是使用動態規劃的思想,
s1每次增加一個字元,看與s2當前位置的字元是不是相同,如果相同做相應的處理,如果不同,做另外的處理。
子序列的處理方式:
相同的情況下,該二維陣列的位置等於[i-1][j-1]+1
不同的情況下,該二維陣列的位置等於MAX(d[i-1][j],d[i][j-1])
下面描述下子串的求法。
最長公共子串,要求字元是連續的。那麼在[s1每次增加一個字元,看與s2當前位置的字元是不是相同]
相同的情況下,二維陣列的位置等於[i-1][j-1]+1,
不同的情況下,二維陣列的位置等於0,最後再檢視二維陣列的資訊即可得到最長公共子串的長度,同時可以回溯二維陣列得到最長公共字串的內容。
----------------------------------------------------------------------------------------------
上面是正確的演算法 錯誤的演算法我也粘貼出來僅供參考
核心
動態規劃
dp【i】【j】 表示 串1 從開始字元到 第i個字元 ,串2從開始字元到第j個字元 ,兩個串中最常公共子串的個數
滿足如下
1.當s1[i] = s2[j] dp[i][j] = d[i-1][j-1]+1(公共子串滿足連續的性質)
2.不等時 dp[i][j] = 0(我不是很理解!求指教,,!!!!!!!!)
#include <stdio.h>
#include <string.h>
#define MAX 200
int dp[MAX][MAX]={
};
int getCommonStrLength(char * pFirstStr, char * pSecondStr)
{
int m = strlen(pFirstStr);
int n = strlen(pSecondStr);
int max = 0;
for( int i = 0;i < m;i ++)
{
for(int j = 0;j < n;j ++)
{
if(pFirstStr[i] == pSecondStr[j])
{
if(i ==0 || j == 0)
{
dp[i][j] = 1;
}
else
{
dp[i][j] = dp[i-1][j-1] + 1;
}
}
if(max < dp[i][j])
{
max = dp[i][j];
}
}
}
return max;
}
int main(void)
{
char s1[200] = {
"\0"
};
char s2[200]= {
"\0"
};
memset(dp+2,0,MAX);
scanf("%s",s1);
scanf("%s",s2);
int num = getCommonStrLength(s1,s2);
printf("%d\n",num);
return 0;
}
------------------------------ps
後最陣列也可實現
kmp演算法 也就是字串查詢演算法 只要是基於後最陣列的都可以實現 (怪不得覺得很眼熟。但是kmp演算法卻一時想不起來 我哭····)
--------------------------------------------------------------
演算法學習還是蠻辛苦的 ,求各位大神指教,給出建議,小弟十分感激