題目:給出兩個字串,找出這兩個字串的公用子字串。
公用子字串和公用序列不同的地方在於 公用子字串要求子串在兩個字串中必須是連續的。
例如:“123579” 和 “2378”公用子字串為“23”,公用子序列為“237”
動態轉移方程為:
如果 xi==yj,則c[i][j] = c[i-1][j-1]+1;
如果xi != yj, 則c[i][j] = 0;
最後求的的長度為max{c[i][j], 1<=i<=n, 1<=j<=m};
代碼如下:
//動態規劃//最長公用字串#include<stdio.h>#include<string.h>#include<malloc.h>#include<assert.h>void Fun(char *str1, char *str2);int main(){char str1[100];char str2[100];printf("輸入字串1\n");gets(str1);printf("輸入字串2\n");gets(str2);Fun(str1, str2);}void Fun(char *str1, char *str2){int length1;int length2;int **Res;int i, j;int max = 0;//公用字串的長度int pos = 0; //公用字串結束的位置length1 = strlen(str1);length2 = strlen(str2);Res = (int **)malloc(sizeof(int *) * (length1+1));assert(Res != NULL);for(i = 0; i < length2+1; ++i){Res[i] = (int *)malloc(sizeof(int) * (length2 + 1));assert(Res[i] != NULL);}for(i = 0; i < length1+1; ++i)Res[i][0] = 0;for(j = 0;j < length2+1; ++j)Res[0][j] = 0;for(i = 1; i < length1+1; ++i){for(j = 1; j < length2+1; ++j){if(str1[i-1] == str2[j-1]){Res[i][j] = Res[i-1][j-1] + 1;}elseRes[i][j] = 0;}}for(i = 0; i < length1+1; ++i) //觀察結果{for(j = 0; j< length2+1; ++j)printf("%2d ", Res[i][j]);printf("\n");}for(i = 0; i < length1+1; ++i)for(j = 0; j < length2 + 1; ++j){if(max < Res[i][j]){max = Res[i][j];pos = i;}}printf("最長公用字串的長度為%d %d\n", max,pos);for(i = pos-max; i < pos; ++i)printf("%c", str1[i]);for(i = 0; i < length1+1; ++i)free(Res[i]);}