題目:輸入乙個字串,求出其中最長的回文子串。子串的含義是:在原串中連續出現的字串片段。回文的含義是:正著看和倒著看相同,如:abba和yyxyy。在判斷時,應該忽略所有的標點符號和空格,且忽略大小寫,但輸出應該保持原樣(在回文串的首部和尾部不要輸出多餘字元)。輸入字串長度不超過5000,且單獨佔據一行。應該輸出最長的回文串,如果有多個,輸出起始位置最靠左的。
樣例輸入:confuciuss say: madam, i'm adam.
樣例輸出:madam, i'm adam
首先可以根據問題要求寫出偽**,為我們解題提供思路:
longestpalindrome:
讀入一行文字。
忽略其中的標點和空格,忽略大小寫,將字母存起來。i : 1->length
j : i->length
如果(是回文串==true)
maxlength = j - i + 1;
輸出maxlength
retrun;
這段**的功能僅僅是找出最長回文串的長度,將其變成c**還是比較簡單的。
首先,讀入一行文字。這裡要考慮到空格的問題,如果用普通的scanf來讀,那只能讀到第乙個空格了,而gets這個函式由於其不安全性,現在已經基本不用了。所以我們這裡用fgets(char *buf, int size, file *fp);這個函式來讀。這個函式每次讀取一行直到'\n'為止。這裡只需要將第三個引數設為stdin(標準輸入)即可。
關於忽略標點空格和大小寫,可以將其中的字母存起來,轉換成大寫字母,其餘字母跳過。
至於回文串的判斷,簡單的遍歷比較即可,但是那樣做太慢了,我們可以用另一種方法,這個方法接下來的改進演算法中會詳述。
第乙個演算法只能解決長度計算問題,現在我們要解決列印問題。最棘手的地方在於:原樣輸出。我們將標點等忽略後,字母在字串中得位置會改變,也就是說,有些字母位置會提前。這樣我們就無法知道字母原來的位置了,所以我們還要存下字母在原字串中的位置。
另外,剛才說簡單的便利比較演算法比較耗時,不能滿足我們的需求,所以我們要改進一下判斷回文串的演算法。所謂回文串,就是從中間乙個(奇數)或兩個(偶數)字元向外擴張,每次遇到的字元都相等。所以我們可以換乙個思路:以第i個位置為中間位置,想兩邊擴張,直到有字元不相等,這時比較新長度與當前最長長度,如果大於當前最長長度,則更新那個最長長度。
這裡需要注意的有兩點:
1、最長回文串的長度是奇數還是偶數,處理方式是不同的。(可以自己舉例試試),主要區別在於中間的字元是乙個還是兩個。
2、由於我們是在轉換後的全是字母的串中操作,所以記錄、更新最大長度的同時也要記錄、更新起止位置,目的是保證最後一步原樣輸出時能找到在原字串中的起始位置。
有了以上理論,不難寫出**:
#define longest_length 5000
/**最長回文子串問題*/
void longgestpalindrome()
}int maxlength = 0;
int start = 0;
int end = 0;
size_t lengthofupper = strlen(upper);
//思路:以i位置的字元作為中間字元,往兩邊擴散查詢回文串
for (int i = 0; i < lengthofupper; i++)
} else
}//最長回文串是奇數的情況
for (int j = 0; (i - j) >= 0 && (i + j + 1) < lengthofupper; j++)
} else }}
for (int i = start; i <= end; i++)
printf("\n");
}
最長回文子串 最長回文子串行
1.最長回文子串行 可以不連續 include include include include using namespace std 遞迴方法,求解最長回文子串行 intlps char str,int i,int j intmain include include include using n...
最長回文子串
描述 輸入乙個字串,求出其中最長的回文子串。子串的含義是 在原串連續出現的字串片段。回文的含義是 正著看和倒著看是相同的,如abba和abbebba。在判斷是要求忽略所有的標點和空格,且忽略大小寫,但輸出時按原樣輸出 首尾不要輸出多餘的字串 輸入字串長度大於等於1小於等於5000,且單獨佔一行 如果...
最長回文子串
輸入乙個字元,求出其中最長的回文子串。子串的含義是 在元串中連續出現的字串片段。回文的含義是 正看和倒看相同,如abba和yyxyy,在判斷時候應該忽略所有的空格和標點符號,且忽略大小寫,但輸出應該保持原樣,輸入的字元長度不超過5000,且佔據單獨一行,輸出最長的回文子串 如有多個,輸出,起始位置最...