子序列、子串问题

#include<iostream>
#include <vector>
using namespace std;

//enum decreaseDire {kInit = 0,kLeft = 1,kUp = 2,kLeftUp = 4};
enum decreaseDire {kInit = 0,kLeft = 1,kUp = 2,kLeftUp = 4};

//打印任意一个公共子序列
void LCS_Print(int **LCS_direction,const char* pStr1,const char* pStr2,size_t row,size_t col)
{
	if(!pStr1 || !pStr2)
		return ;
	size_t length1 = strlen(pStr1);
	size_t length2 = strlen(pStr2);
	if(length1 == 0 || length2 == 0)
		return ;
	if(row>=length1 || col>=length2 || row<0 || col<0)
		return ;
	if(LCS_direction[row][col] == kLeftUp){
		LCS_Print(LCS_direction,pStr1,pStr2,row-1,col-1);	printf("%c",pStr1[row]);
	}else if(LCS_direction[row][col] == kLeft){
		LCS_Print(LCS_direction,pStr1,pStr2,row,col-1);
	}else if(LCS_direction[row][col] == kUp){
		LCS_Print(LCS_direction,pStr1,pStr2,row-1,col);
	}
	return ;
}
//打印任意所有公共子序列
void LCS_Print_AllSeq(int **LCS_direction,const char* pStr1,const char* pStr2,size_t row,size_t col,char *result,int start)
{
	if(!pStr1 || !pStr2)
		return ;
	size_t length1 = strlen(pStr1);
	size_t length2 = strlen(pStr2);
	if(length1 == 0 || length2 == 0)
		return ;
	if(row>=length1 || col>=length2 || row<0 || col<0){
		printf("%s\n",result+start+1);
		return ;
	}
	switch(LCS_direction[row][col]){
		case kLeft:
			LCS_Print_AllSeq(LCS_direction,pStr1,pStr2,row,col-1,result,start);
			break;
		case kUp:
			LCS_Print_AllSeq(LCS_direction,pStr1,pStr2,row-1,col,result,start);
			break;
		case kLeftUp:
			result[start] = pStr1[row];
			LCS_Print_AllSeq(LCS_direction,pStr1,pStr2,row-1,col-1,result,start-1);	//printf("%c",pStr1[row]);
			break;
		case kLeft+kUp:
			LCS_Print_AllSeq(LCS_direction,pStr1,pStr2,row,col-1,result,start);
			LCS_Print_AllSeq(LCS_direction,pStr1,pStr2,row-1,col,result,start);
			break;
		case kLeft+kLeftUp:
			LCS_Print_AllSeq(LCS_direction,pStr1,pStr2,row,col-1,result,start);
			LCS_Print_AllSeq(LCS_direction,pStr1,pStr2,row-1,col-1,result,start-1);	//printf("%c",pStr1[row]);
			break;
		case kUp+kLeftUp:
			LCS_Print_AllSeq(LCS_direction,pStr1,pStr2,row-1,col,result,start);
			LCS_Print_AllSeq(LCS_direction,pStr1,pStr2,row-1,col-1,result,start-1);	//printf("%c",pStr1[row]);
			break;
		case kLeft+kUp+kLeftUp:
			LCS_Print_AllSeq(LCS_direction,pStr1,pStr2,row,col-1,result,start);
			LCS_Print_AllSeq(LCS_direction,pStr1,pStr2,row-1,col,result,start);
			LCS_Print_AllSeq(LCS_direction,pStr1,pStr2,row-1,col-1,result,start-1);	//printf("%c",pStr1[row]);
			break;
	}
// 	if(LCS_direction[row][col] == kLeftUp){
// 		LCS_Print(LCS_direction,pStr1,pStr2,row-1,col-1);	printf("%c",pStr1[row]);
// 	}
// 	if(LCS_direction[row][col] == kLeft){
// 		LCS_Print(LCS_direction,pStr1,pStr2,row,col-1);
// 	}
// 	if(LCS_direction[row][col] == kUp){
// 		LCS_Print(LCS_direction,pStr1,pStr2,row-1,col);
// 	}
}
//subsequence
int LCS(const char* pStr1,const char* pStr2)
{
	if(!pStr1 || !pStr2)
		return 0;
	size_t length1 = strlen(pStr1);
	size_t length2 = strlen(pStr2);
	if(length1 == 0 || length2 == 0)
		return 0;

	int **LCS_length,**LCS_direction;
	size_t i,j;
	LCS_length = new int*[length1];	LCS_direction = new int*[length1];
	for(i=0;i<length1;i++){
		LCS_length[i] = new int[length2];	LCS_direction[i] = new int[length2];
	}
	for(i=0;i<length1;i++){
		for(j=0;j<length2;j++){
			LCS_length[i][j] = 0;	LCS_direction[i][j] = kInit;
		}
	}
	for(i=0;i<length1;i++){
		for(j=0;j<length2;j++){
			if(i==0 || j==0){
				if(pStr1[i] == pStr2[j]){
					LCS_length[i][j] = 1;					LCS_direction[i][j] = kLeftUp;
				}
			}else if(pStr1[i] == pStr2[j]){
				LCS_length[i][j] = LCS_length[i-1][j-1]+1;	LCS_direction[i][j] = kLeftUp;
			}else if(LCS_length[i-1][j] >= LCS_length[i][j-1]){
				LCS_length[i][j] = LCS_length[i-1][j];		LCS_direction[i][j] = kUp;
			}else{
				LCS_length[i][j] = LCS_length[i][j-1];		LCS_direction[i][j] = kLeft;
			}
			//printf("%2d ",LCS_length[i][j]);
			printf("%2d ",LCS_direction[i][j]);
		}
		printf("\n");
	}
	LCS_Print(LCS_direction,pStr1,pStr2,length1-1,length2-1);
	return LCS_length[length1-1][length2-1];
}
//AllSeq
int LCS_AllSeq(const char* pStr1,const char* pStr2)
{
	if(!pStr1 || !pStr2)
		return 0;
	size_t length1 = strlen(pStr1);
	size_t length2 = strlen(pStr2);
	if(length1 == 0 || length2 == 0)
		return 0;

	int **LCS_length,**LCS_direction;
	size_t i,j;
	LCS_length = new int*[length1];	LCS_direction = new int*[length1];
	for(i=0;i<length1;i++){
		LCS_length[i] = new int[length2];	LCS_direction[i] = new int[length2];
	}
	for(i=0;i<length1;i++){
		for(j=0;j<length2;j++){
			LCS_length[i][j] = 0;	LCS_direction[i][j] = kInit;
		}
	}
	for(i=0;i<length1;i++){
		for(j=0;j<length2;j++){
			if(i==0 && j==0){
				if(pStr1[i] == pStr2[j]){
					LCS_length[i][j] = 1;					LCS_direction[i][j] += kLeftUp;
				}
			}else if(i==0 || j==0){
				if(pStr1[i] == pStr2[j]){
					LCS_length[i][j] = 1;					LCS_direction[i][j] += kLeftUp;
				}
				if(i==0){
					if(LCS_length[i][j-1] == 1){
						LCS_length[i][j] = 1;
						LCS_direction[i][j] += kLeft;
					}
				}else{
					if(LCS_length[i-1][j] == 1){
						LCS_length[i][j] = 1;
						LCS_direction[i][j] += kUp;
					}
				}
			}
			if(i!=0 && j!=0){
				if(pStr1[i] == pStr2[j]){
					LCS_length[i][j] = LCS_length[i-1][j-1]+1;	LCS_direction[i][j] += kLeftUp;
					if(LCS_length[i-1][j] == LCS_length[i][j]){
						LCS_direction[i][j] += kUp;
					}
					if(LCS_length[i][j-1] == LCS_length[i][j]){
						LCS_direction[i][j] += kLeft;
					}
				}else{
					if(LCS_length[i-1][j] == LCS_length[i][j-1]){
						LCS_length[i][j] = LCS_length[i-1][j];
						LCS_direction[i][j] += kUp;
						LCS_direction[i][j] += kLeft;						
					}else if(LCS_length[i-1][j] > LCS_length[i][j-1]){
						LCS_length[i][j] = LCS_length[i-1][j];
						LCS_direction[i][j] += kUp;
					}else{
						LCS_length[i][j] = LCS_length[i][j-1];
						LCS_direction[i][j] += kLeft;			
					}
				}
			}
			printf("%2d ",LCS_direction[i][j]);
			//printf("%2d ",LCS_length[i][j]);
		}
		printf("\n");
	}
	char *result = new char[length1+1];
	result[length1] = '\0';
	LCS_Print_AllSeq(LCS_direction,pStr1,pStr2,length1-1,length2-1,result,length1-1);
	return LCS_length[length1-1][length2-1];
}
//substring
int LCString(const char* pStr1,const char* pStr2)
{
	if(!pStr1 || !pStr2)
		return 0;
	size_t length1 = strlen(pStr1);
	size_t length2 = strlen(pStr2);
	if(length1 == 0 || length2 == 0)
		return 0;

	int **LCS_length,**LCS_direction;
	size_t i,j;
	LCS_length = new int*[length1];	LCS_direction = new int*[length1];
	for(i=0;i<length1;i++){
		LCS_length[i] = new int[length2];	LCS_direction[i] = new int[length2];
	}
	for(i=0;i<length1;i++){
		for(j=0;j<length2;j++){
			LCS_length[i][j] = 0;	LCS_direction[i][j] = kInit;
		}
	}
	int maxLen = 0;int maxI = 0,maxJ = 0;
	for(i=0;i<length1;i++){
		for(j=0;j<length2;j++){
			if(i==0 || j==0){
				if(pStr1[i] == pStr2[j]){
					LCS_length[i][j] = 1;					LCS_direction[i][j] = kLeftUp;
				}
			}else if(pStr1[i] == pStr2[j]){
				if(LCS_direction[i-1][j-1] = kLeftUp){
					LCS_length[i][j] = LCS_length[i-1][j-1]+1;	LCS_direction[i][j] = kLeftUp;
				}
				else{
					LCS_length[i][j] = 1;						LCS_direction[i][j] = kLeftUp;
				}
			}
			if(LCS_length[i][j] > maxLen){
				maxLen = LCS_length[i][j];
				maxI = i;	maxJ = j;
			}
		}
	}
	//LCS_Print(LCS_direction,pStr1,pStr2,length1-1,length2-1);
	//return LCS_length[length1-1][length2-1];
	LCS_Print(LCS_direction,pStr1,pStr2,maxI,maxJ);
	return maxLen;
}

int main()
{
	char Str1[] = "BDCABA",Str2[] = "ABCBDAB";
	//char Str1[] = "dhajhfakdfjkahfahakjhfjahyfhgqioqurjdnachhzjjckaghda",Str2[] = "qyuiaudhajndjahdfjajdalkfdyi8qyahjkdhajhdfahfjhasfka";
	//char Str1[] = "dhajhfakdfjkahfahakjhfa",Str2[] = "qyuiaudhajndjahdhasfka";
	int Len;
	//Len = LCS(Str1,Str2);			//子串
	//Len = LCS_AllSeq(Str1,Str2);	//所有子串
	Len = LCString(Str1,Str2);		//子序列
	cout<<endl<<Len<<endl;
	return 0;
}

你可能感兴趣的:(子序列、子串问题)