1. 程式人生 > >2238"回文字串"報告

2238"回文字串"報告

操作 void char 都是 暴力 查找 回文子串 -- 標記

題目描述:

回文串,就是從前往後和從後往前看都是一樣的字符串。那麽現在給你一個字符串,請你找出該字符串中,長度最大的一個回文子串。

輸入描述:

有且僅有一個僅包含小寫字母的字符串,保證其長度不超過5000

輸出描述:

有且僅有一個正整數,表示最長回文子串的長度

輸入樣例:

abccbxyz

輸出樣例:

4

分析:

我的算法算是比較暴力的。這道題目中,需要輸出最長的回文字串的長度,我的想法是從最長的長度開始尋找是否有回文字串符合這個長度,如果沒有,則從次長的長度尋找是否有符合長度的回文字串。比如說,給定abccbxyz,它們分別對應a[0]-a[7],我們先從長度最長,也就是8開始查找,然後從a[0]開始尋找,如果a[0]和它後面的第(0 + 8 - 1)個數字相等,那麽這個數字可能是回文字串,此時,從a[0 + 1]和a[8 - 2]開始比較,也就是字符串往中間收,如果有一組對應的字符不相等,那麽就不是回文字串,接著就從a[1]為起點開始和a[1 + 8 - 1]開始比較,之後的過程和前面一樣,當找到符合長度的回文字串是,就可以輸出這個長度,然後結束。需要註意的是,每一個回文字串的起點的範圍是:0-p - k,其中p是總字符串的長度,k是要尋找的長度,因為一旦起點大於p-k,那麽終點為p-k+k等於p,而數組是這個下標代表的是‘\0‘。接下來,代碼就很容易寫出來了。

代碼:

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

int main(void)
{
char a[5001];
int k,l,p,flag1,flag2,i,j,m,flag,flag3;
scanf ("%s",a);
p = strlen(a);//算出字符串的長度
for (k = p; k >= 1; k--)//k為需要尋找符合長度的回文字串的長度,從後往前找
{
flag3 = 0;//標記是否找到了符合長度的回文字串
for (i = 0; i <= p - k; i++)//起點的範圍從0到p-k
{
if(a[i] == a[i + k - 1])//起點和終點相等,就需要開始比較這個字串
{
flag = 1;
if(k > 3)//當字串長度小於等於3時,如果起點相等,那麽一定是回文串,則不需要進行下面的操作
{
for (flag1 = i + 1,flag2 = i + k - 2,m = i + k / 2 - 1; flag1 <= m; flag1++,flag2--)//從起點和終點往中間收
{
if(a[flag1] != a[flag2])//有一組對應的不相等,則不是回文串
{
flag = 0;
break;
}

}
}
else//k <= 3,當字串長度小於等於3時,如果起點相等,那麽一定是回文串
{
flag3 = 1;
break;
}
if(flag)
{
flag3 = 1;//當沒有對應的不相等,那麽是回文串,進行標記表示找到了
break;
}
}
}
if(flag3)//找到了最長的回文字串,輸出該長度,結束
{
printf ("%d\n",k);
break;
}
}

return 0;
}

總結:這種算法比較好理解,但也比較復雜,因為其時間復雜度是O(n^2),能A是因為數據還不算太大~

2238"回文字串"報告