問題描述:
迴文字符串,也即正反兩個方向讀取的字符串應該一樣。比如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