1. 程式人生 > >動態規劃基礎篇之最長公共子序列問題

動態規劃基礎篇之最長公共子序列問題

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int max1(int m,int n)
{
	if(m>n)
		return m;
	else
		return n;
}
int max2(int x,int y,int z,int k,int m,int n)
{
	int max=-1;
	if(x>max)
		max=x;
	if(y>max)
		max=y;
	if(z>max)
		max=z;
	if(k>max)
		max=k;
	if(m>max)
		max=m;
	if(n>max)
		max=n;
	return max;
}
int LCSLength(char* str1, char* str2, char* str3) //求得三個字串的最大公共子序列長度並輸出公共子序列
{
	int i,j,k,length1,length2,length3,len;
	length1 = strlen(str1);
	length2 = strlen(str2);
	length3 = strlen(str3);

	//申請動態三維陣列
	int ***c = new int**[length1+1];      //共有length1+1行
	for(i = 0; i < length1+1; i++)
	{
		c[i] = new int*[length2+1];      //共有length2+1列
		for(j = 0; j<length2+1; j++)
			c[i][j] = new int[length3+1];
	}

	for(i = 0; i < length1+1; i++)
	{
		for(j = 0; j < length2+1; j++)
			c[i][j][0]=0;
	}
	for(i = 0; i < length2+1; i++)
	{
		for(j = 0; j < length3+1; j++)
			c[0][i][j]=0;
	}
	for(i = 0; i < length1+1; i++)
	{
		for(j = 0; j < length3+1; j++)
			c[i][0][j]=0;
	}

	for(i = 1; i < length1+1; i++)
	{
		for(j = 1; j < length2+1; j++)
		{
			for(k = 1; k < length3+1; k++)
			{
				if(str1[i-1]==str2[j-1] && str2[j-1]==str3[k-1])
					c[i][j][k]=c[i-1][j-1][k-1]+1;
				else if(str1[i-1]==str2[j-1] && str1[i-1]!=str3[k-1])
					c[i][j][k]=max1(c[i][j][k-1],c[i-1][j-1][k]);
				else if(str1[i-1]==str3[k-1] && str1[i-1]!=str2[j-1])
					c[i][j][k]=max1(c[i][j-1][k],c[i-1][j][k-1]);
				else if(str2[j-1]==str3[k-1] && str1[i-1]!=str2[j-1])
					c[i][j][k]=max1(c[i-1][j][k],c[i][j-1][k-1]);
				else
				{
					c[i][j][k]=max2(c[i-1][j][k],c[i][j-1][k],c[i][j][k-1],c[i-1][j-1][k],c[i-1][j][k-1],c[i][j-1][k-1]);
				}
			}
		}
	}
	len=c[length1][length2][length3];
	for(i = 1; i < length1+1; i++) //釋放動態申請的三維陣列
	{
		for(j = 1; j < length2+1; j++)
			delete[] c[i][j];
		delete[] c[i];
	}
	delete[] c;
	return len;
}

int main(void)
{
	char str1[100],str2[100],str3[100];
	int len;

	printf("請輸入第一個字串:");
	gets(str1);
	printf("請輸入第二個字串:");
	gets(str2);
	printf("請輸入第三個字串:");
	gets(str3);
	len=LCSLength(str1,str2,str3);
	printf("最長公共子序列的長度為:%d\n",len);
	system("pause");
	return 0;
}