最大對(duì)稱字符串的算法
算法一:O(n^3)
判斷字串是否對(duì)稱是從外到里, O(n)
#include <stdio.h>
#include <string.h>
/*
*判斷起始指針,到結(jié)束指針的字符串是否對(duì)稱
*/
int IsSymmetrical(char* pBegin, char* pEnd)
{
if(pBegin == NULL || pEnd == NULL || pBegin > pEnd)
return 0;
while(pBegin < pEnd)
{
if(*pBegin != *pEnd)
return 0;
pBegin++;
pEnd--;
}
return 1;
}
/*
*查找最大對(duì)稱字串長(zhǎng)度,時(shí)間復(fù)雜度是O(n^3)
*/
int GetLongestSymmetricalLength(char* pString)
{
if(pString == NULL)
return 0;
int symmetricalLength = 1;
char* pFirst = pString;
int length = strlen(pString);
while(pFirst < &pString[length-1])
{
char* pLast = pFirst + 1;
while(pLast <= &pString[length-1])
{
if(IsSymmetrical(pFirst, pLast))
{
int newLength = pLast - pFirst + 1;
if(newLength > symmetricalLength)
symmetricalLength = newLength;
}
pLast++;
}
pFirst++;
}
return symmetricalLength;
}
int main()
{
char* str = "google";
int len = GetLongestSymmetricalLength(str);
printf("%d", len);
return 0;
}
算法2: O(n^2)
判斷字串是否對(duì)稱是從外到里, O(1)
#include <stdio.h>
#include <string.h>
int GetLongestSymmetricalLength(char* pString)
{
if(pString == NULL)
return 0;
int symmetricalLength = 1;
char* pChar = pString;
while(*pChar != '\0')
{
//奇數(shù)長(zhǎng)度對(duì)稱, 如 aAa
char* left = pChar - 1;
char* right = pChar + 1;
while(left >= pString && *right != '\0' && *left==*right)
{
left--;
right++;
}
int newLength = right - left - 1; //退出循環(huán)是*left!=*right
if(newLength > symmetricalLength)
symmetricalLength = newLength;
//偶數(shù)長(zhǎng)度對(duì)稱, 如 aAAa
left = pChar;
right = pChar + 1;
while(left >= pString && *right != '\0' && *left==*right)
{
left--;
right++;
}
newLength = right - left - 1; //退出循環(huán)是*left!=*right
if(newLength > symmetricalLength)
symmetricalLength = newLength;
pChar++;
}
return symmetricalLength;
}
int main()
{
char* str = "google";
int len = GetLongestSymmetricalLength(str);
printf("%d", len);
return 0;
}
算法3:manacher算法
原串:abaab
新串:#a#b#a#a#b#
這樣一來(lái),原來(lái)的奇數(shù)長(zhǎng)度回文串還是奇數(shù)長(zhǎng)度,偶數(shù)長(zhǎng)度的也變成以‘#'為中心的奇數(shù)回文串了。
接下來(lái)就是算法的中心思想,用一個(gè)輔助數(shù)組P記錄以每個(gè)字符為中心的最長(zhǎng)回文半徑,也就是P[i]記錄以Str[i]字符為中心的最長(zhǎng)回文串半徑。P[i]最小為1,此時(shí)回文串為Str[i]本身。
我們可以對(duì)上述例子寫出其P數(shù)組,如下
新串: # a # b # a # a # b #
P[] : 1 2 1 4 1 2 5 2 1 2 1
我們可以證明P[i]-1就是以Str[i]為中心的回文串在原串當(dāng)中的長(zhǎng)度。
證明:
1、顯然L=2*P[i]-1即為新串中以Str[i]為中心最長(zhǎng)回文串長(zhǎng)度。
2、以Str[i]為中心的回文串一定是以#開頭和結(jié)尾的,例如“#b#b#”或“#b#a#b#”所以L減去最前或者最后的‘#'字符就是原串中長(zhǎng)度的二倍,即原串長(zhǎng)度為(L-1)/2,化簡(jiǎn)的P[i]-1。得證。
注: 不是很懂, 自己改了
#include <stdio.h>
#include <string.h>
int GetLongestSymmetricalLength(char* pString)
{
int length = strlen(pString);
char* pNewString = malloc(2*length+2);
int i;
for(i=0; i<length; i++)
{
*(pNewString+i*2) = '#';
*(pNewString+i*2+1) = *(pString+i);
}
*(pNewString+2*length) = '#';
*(pNewString+2*length+1) = '\0';
printf("%s\n", pNewString);
int maxLength = 1;
char* pChar;
for(i=0; i<2*length+2; i++)
{
int newLength = 1;
pChar = pNewString + i;
char* left = pChar-1;
char* right = pChar+1;
while(left>=pNewString && *right!='\0'&& *left==*right)
{
left--;
right++;
newLength++;
}
if(newLength > maxLength)
maxLength = newLength;
}
return maxLength-1;
}
int main()
{
char* str = "google";
int len = GetLongestSymmetricalLength(str);
printf("%d", len);
return 0;
}
相關(guān)文章
C++11中內(nèi)聯(lián)函數(shù)(inline)用法實(shí)例
內(nèi)聯(lián)函數(shù)本質(zhì)還是一個(gè)函數(shù),但在聲明的時(shí)候,函數(shù)體要和聲明結(jié)合在一起,否則編譯器將它作為普通函數(shù)來(lái)對(duì)待,下面這篇文章主要給大家介紹了關(guān)于C++11中內(nèi)聯(lián)函數(shù)(inline)的相關(guān)資料,需要的朋友可以參考下2022-10-10
C語(yǔ)言版約瑟夫問(wèn)題算法實(shí)現(xiàn)
大家好,本篇文章主要講的是C語(yǔ)言版約瑟夫問(wèn)題算法實(shí)現(xiàn),感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你又幫助的話記得收藏一下,方便下次瀏覽2021-12-12
C++隱式類型轉(zhuǎn)換運(yùn)算符operator type()用法詳解
這篇文章主要介紹了C++隱式類型轉(zhuǎn)換運(yùn)算符operator type()用法詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06
C語(yǔ)言實(shí)現(xiàn)動(dòng)態(tài)開辟存儲(chǔ)楊輝三角
這篇文章主要介紹了如何利用C語(yǔ)言實(shí)現(xiàn)動(dòng)態(tài)開辟存儲(chǔ)楊輝三角,可以靈活的開辟空間,充分的利用空間。文中的示例代碼講解詳細(xì),感興趣的小伙伴可以參考一下2022-03-03
使用單鏈表實(shí)現(xiàn)多項(xiàng)式計(jì)算示例
這篇文章主要介紹了使用單鏈表實(shí)現(xiàn)多項(xiàng)式計(jì)算示例,需要的朋友可以參考下2014-03-03

