搜尋最長迴文子串的解法之比較

問題描述:

迴文字符串,也即正反兩個方向讀取的字符串應該一樣。比如ABCDCBA。

        本文的問題是,給定一個字符串輸出其最長的迴文串。


解決方法:

1.暴力搜索(Brute force)

        2.動態規劃(dynamic programming)

               假定:inputStr 爲輸入串

               table[head][tail]:表示頭方向從head開始,尾方向從tail開始,是否存在迴文串,

               若存在,table[head][tail] = 1,否則table[head][tail] = 0;

     狀態轉移方程:table[head][tail] = 1,當table[head+1][tail=-1] = 1 且 inputStr[head] == inputStr[tail];

 

源代碼:

#ifndef _DAYNAMIC_PROGRAMMINGSET_H_
#define _DAYNAMIC_PROGRAMMINGSET_H_

#include <string>
#include <stdlib.h>
#include <stdio.h>


/*
*
*
*/
template<class T>
T  MaxValue( const T& first, const T& second )
{
	if( first > second )
	{
		return first;
	}

	return second;
}


/*
* The implementation of the method of brute force
*
*/
int LongPalindromicSubstrBrute( const char* str, std::string& palinDromicStr )
{
	int maxVal = -1;
	size_t len = strlen( str );
	int startIdx = -1;

	for( int i = 0; i < len; i++ )
	{
		int start = i;
		int maxLenStr = 0;
		for( int j =  len - 1; j >= start; j-- )
		{
			if( str[start] == str[j] )
			{
				start++;
				maxLenStr += 2;
			}
			else
			{
				maxLenStr = 0;
				start = i;
			}
		}

		if( maxLenStr > maxVal  )
		{
			startIdx = i;
			maxVal = maxLenStr;
		}
	}

	std::string strObj(str);
	palinDromicStr = strObj.substr( startIdx, maxVal );

	return maxVal;
}

/*
* helper function
*
*/
void ConstructTable( size_t tableLen, int**& table )
{
	table = new int*[tableLen];
	assert( table );

	for( int i = 0; i < tableLen; i++ )
	{
		table[i] = new int[ tableLen ];
		memset( table[i], 0x00, sizeof(int)*(tableLen ));
		assert( table[i] );
	}
}


/*
* helper function
*
*/
void DestructTable( size_t tableLen, int** table )
{
	for( int i = 0; i < tableLen; i++ )
	{
		delete [] table[i];
	}

	delete [] table;
}

/*
* the implementation of dynamic programming
*
*/
int LongPalindromicSubstrDPExt( const char* str, std::string& palindromicStr )
{
	size_t strLen = strlen( str );
	int** table = 0;
	ConstructTable( strLen + 1, table );

	for( int i = 0; i <= strLen; i++ )
		table[i][i] = 1;

	int curidx = 0;
	int maxLen = -1;
	for( int i = 0; i < strLen - 1; i++ )
	{
		if( str[i] == str[i + 1] )
		{
			table[i][i + 1] = 1;
			maxLen = 2;
			curidx = i;
		}
	}


	for( int i = 3; i <= strLen; i++ )
	{
		//head pos index
		for( int head = 0; head < strLen - i + 1; head++ )
		{
			//tail pos index
			int tail = head + i - 1;
			if( table[head + 1][tail - 1] && str[head] == str[tail] )
			{
				table[head][tail] = 1;
				if( i > maxLen )
				{
					maxLen = i;
					curidx = head;
				}
			}

		}
	}

	std::string strObj(str);
	palindromicStr = strObj.substr( curidx, maxLen );

	DestructTable( strLen + 1, table );

	return maxLen;

}

/*
* the implementation of dynamic programming
*
*/
int LongPalindromicSubstrDP( const char* str, std::string& palindromicStr )
{
	size_t strLen = strlen( str );
	int** table = 0;
	ConstructTable( strLen + 1, table );

	for( int i = 0; i <= strLen; i++ )
		table[i][i] = 1;

	for( int i = 0; i < strLen - 1; i++ )
	{
		if( str[i] == str[i + 1] )
			table[i][i + 1] = 1;
	}

	int maxLen = -1;
	int curidx = -1;
	for( int i = strLen - 1; i > 0; i-- )
	{
		for( int j = i + 1; j < strLen; j++ )
		{
			if( str[i] == str[j] && table[i][j] )
			{
				table[i-1][j+1] = table[i][j];

				int len = j - i + 1;
				if( len > maxLen )
				{
					maxLen = len;
					curidx = i;
				}
			}
		}
	}

	
	std::string strObj(str);
	palindromicStr = strObj.substr( curidx, maxLen );
	DestructTable( strLen + 1, table );


	return maxLen;

}





/*
* Test interface
*
*/
void TestLongPalinromicSubstr()
{
	//const char* str = "abcdedcba";
	const char* str = "weewetttcfrdddgeeksskeegdddfcewwwssssrfffrrrrwwwr\
		               eaqwwwaacdddddoeoededleegdefgefefkegeeffsskkkmced";
	size_t strLen = strlen( str );


	std::string strObj;
	int res = LongPalindromicSubstrBrute( str, strObj );
	printf( "palindromic substr is %s by brute force method \n", strObj.c_str() );

	strObj.clear();
	res = LongPalindromicSubstrDP( str, strObj );
	printf( "palindromic substr is %s by dynamic programming \n", strObj.c_str() );


	
	strObj.clear();
	res = LongPalindromicSubstrDPExt( str, strObj );
	printf( "palindromic substr is %s by dynamic programming extended \n", strObj.c_str() );

}





#endif 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章