有关回文串的问题,可能涉及到判断一个字符串是否是回文串、求最大回文子串长度或者求至少添加多少个字符使得输入字符串称为回文串。这些问题我都已经解决,为了使用方便,我把这些实现代码都粘出来了。
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 /** 6 * @brief 检测字符串是否为回文字符串,如果是,返回1;否则,返回0 7 */ 8 int isPalindrome(char s[], int len){ 9 int i, mid = len / 2; 10 11 if (len == 1) return 1; 12 13 for (i = 0; i < mid; i++){ 14 if (s[i] != s[len - i - 1]) 15 return 0; 16 } 17 return 1; 18 } 19 20 //穷举策略:O(n^3) 21 int getMaxPalindrome1(char s[], int len, int *start) 22 { 23 printf("O(N^3) method. "); 24 //offset是子串起始相对于输入字符串起始的偏移量,j是子串长度 25 int offset = 0, j = len; 26 int maxLen = 0;//存储回文子串的最大长度 27 28 if (len <= 1) return -1;//出错 29 30 while (offset < len){//子串起始逐个后移 31 j = len - offset;//j初始化为可获得的最大子串长度 32 while (j > 1){ 33 if (isPalindrome(s+offset, j)){ 34 if (maxLen < j){ 35 maxLen = j; 36 *start = offset;//记录最大子串的偏移 37 } 38 } 39 j--;//缩短子串 40 } 41 offset++;//偏移量后移 42 } 43 44 return maxLen; 45 } 46 47 //此算法仍然可以继续优化,在知道maxLen值的情况下,我们可以直接 48 //寻找以offset为中心比maxLen大一个的长度来初始化left和right 49 //的初始值,算法更加高效. 50 int getMaxPalindrome2(char s[], int len, int *start) 51 { 52 printf("O(N^2) method. "); 53 54 //奇数长度子串和偶数长度子串的最大回文长度 55 int offset = 0, maxLen = 0, oddLen, evenLen; 56 int left, right;//分别指向子串的左右边界 57 58 if (len <= 1) return -1; 59 60 while (offset < len){ 61 //奇数长度子串的情况 62 left = offset - 1; 63 right = offset + 1; 64 oddLen = 1;//初始化最大奇数回文长度为1 65 //while (left >= 0 && right < len && isPalindrome(s+left, right-left+1)){ 66 while (left >= 0 && right < len && s[left] == s[right]){ 67 left--; 68 right++; 69 oddLen += 2; 70 } 71 if (oddLen > maxLen){ 72 maxLen = oddLen; 73 *start = ++left; 74 } 75 76 //偶数长度子串的情况 77 left = offset; 78 right = offset + 1; 79 evenLen = 0;//初始化最大偶数回文长度为0 80 //while (left >= 0 && right < len && isPalindrome(s+left, right-left+1)){ 81 while (left >= 0 && right < len && s[left] == s[right]){ 82 left--; 83 right++; 84 evenLen += 2; 85 } 86 if (evenLen > maxLen){ 87 maxLen = evenLen; 88 *start = ++left; 89 } 90 91 //偏移量自加 92 offset++; 93 } 94 95 return maxLen; 96 } 97 98 // Manacher算法实现 99 // 对原字符串进行预处理 100 // srcstr[] 原字符数组 head:新串起始标志 separator:字符之间的分隔符 101 char* prepare(char srcstr[], int len, char head, char separator) 102 { 103 int i, length = len; 104 char *newstr = (char*)malloc(2*length + 3); 105 newstr[0] = head; 106 for (i = 0; i < length; i++){ 107 newstr[2*i+1] = separator; 108 newstr[2*i+2] = srcstr[i]; 109 } 110 newstr[2*length+1] = separator; 111 newstr[2*length+2] = '