编写回文编程思路可以分为以下几个步骤:
理解回文定义
回文是指一个字符串从前往后读和从后往前读是相同的,即中心对称。
构造回文
给定一个字符串,可以通过删除一些字符使得剩下的字符串是一个回文串。目标是找到最长的回文子串,并输出需要删除的字符个数。
双指针法
使用两个指针,一个指向字符串的开头,一个指向字符串的末尾,然后逐步向中间移动,比较对应位置的字符。如果所有对应位置的字符都相同,则该字符串是回文。这种方法的时间复杂度是O(n),其中n是字符串的长度。
中心扩展法
从字符串的每个字符开始,向两边扩展,检查以该字符为中心的回文子串。这种方法的时间复杂度也是O(n^2),但通常比双指针法更快找到最长的回文子串。
Manacher算法
通过预处理字符串,使得所有子串都是奇数长度,并在中间插入分隔符,从而避免区分回文的前缀和后缀。通过计算每个字符的回文半径,可以在O(n)时间内找到最长的回文子串。这种方法的空间复杂度为O(n),时间复杂度为O(n)。
动态规划
使用一个二维数组dp,其中dp[i][j]表示区间i到j的最大回文子串长度。通过递推关系,可以找到最长的回文子串。这种方法的时间复杂度为O(n^2),空间复杂度为O(n^2)。
示例代码(双指针法)
```cpp
include include include using namespace std; bool isPalindrome(const string& s) { int left = 0; int right = s.length() - 1; while (left < right) { if (s[left] != s[right]) { return false; } left++; right--; } return true; } int main() { string input; cout << "请输入一个字符串: "; getline(cin, input); if (isPalindrome(input)) { cout << "是回文字符串" << endl; } else { cout << "不是回文字符串" << endl; } return 0; } ``` 示例代码(中心扩展法) ```cpp include include include using namespace std; string longestPalindrome(const string& s) { string maxStr = ""; for (int i = 0; i < s.length(); i++) { // 以 s[i] 为中心的回文子串 string str = s.substr(i, 1); int left = i - 1; int right = i + 1; while (left >= 0 && right < s.length() && s[left] == s[right]) { str += s[left]; left--; right++; } if (str.length() > maxStr.length()) { maxStr = str; } // 以 s[i] 和 s[i+1] 为中心的回文子串 str = s.substr(i, 2); left = i - 1; right = i + 1; while (left >= 0 && right < s.length() && s[left] == s[right]) { str += s[left]; left--; right++; } if (str.length() > maxStr.length()) { maxStr = str; } } return maxStr; } int main() { string input; cout << "请输入一个字符串: "; getline(cin, input); string result = longestPalindrome(input); cout << "最长的回文子串是: " << result << endl; return 0; } ``` 示例代码(Manacher算法)