第一篇链接:字符串类习题、面试题具体解释(第一篇)
6题:回文串(竞赛基础题)
输入一个字符串,求出其最长回文子串。子串的含义是:在原串中连续出现的字符串片段。回文的含义是:正着看和倒着看同样,如abba和yyxyy。在推断时,应该忽略全部标点符号和空格,且忽略大写和小写,但输出应保持原样(在回文串的首部和尾部不要输出多余字符)。输入字符串长度不超过5000,且占领单独一行。应该输出最长的回文串,假设有多个,输出起始位置最靠左的。
例子输入:Confuciuss say: Madam, I’m Adam.
例子输出:Madam,I’m Adam
方法1:枚举回文串的起点和终点。
#include <stdio.h> #include <ctype.h> #include <string.h> #define MAXN 5000 + 10 char buf[MAXN], s[MAXN]; int p[MAXN]; int main(void) { int n, m = 0, max = 0, x, y; int i, j, k, ok; fgets(buf, sizeof(buf), stdin); n = strlen(buf); for (i = 0; i < n; i++) { if (isalpha(buf[i])) { p[m] = i; //保存字符的实际位置 s[m++] = toupper(buf[i]); //保存为大写字母 } } for (i = 0; i < m; i++) //枚举回文串起始位置 { for (j = i; j < m; j++) //枚举回文串终止位置 { ok = 1; for (k = i; k <= j; k++) { if (s[k] != s[i + j - k]) ok = 0; } if (ok && j - i + 1 > max) { max = j - i + 1; x = p[i]; y = p[j]; } } } for (i = x; i <= y; i++) { printf("%c", buf[i]); } printf(" "); return 0; }方法2:枚举回文串的中间位置。
#include <stdio.h> #include <string.h> #include <ctype.h> #define MAXN 5000 + 10 char buf[MAXN], s[MAXN]; int p[MAXN]; int main(void) { int n, m = 0, max = 0, x, y; int i, j; fgets(buf, sizeof(buf), stdin); n = strlen(buf); for (i = 0; i < n; i++) { if (isalpha(buf[i])) { p[m] = i; //保存字符实际位置 s[m++] = toupper(buf[i]); } } for (i = 0; i < m; i++) //枚举回文串的中间位置 { for (j = 0; i - j >= 0 && i + j < m; j++) //回文子串长度为奇数 { if (s[i - j] != s[i + j]) break; if (j * 2 + 1 > max) { max = j * 2 + 1; x = p[i - j]; y = p[i + j]; } } for (j = 0; i - j >= 0 && i + j + 1 < m; j++) //回文串长度为偶数 { if (s[i - j] != s[i + j + 1]) break; if (j * 2 + 2 > max) { max = j * 2 + 2; x = p[i - j]; y = p[i + j + 1]; } } } for (i = x; i <= y; i++) printf("%c", buf[i]); printf(" "); return 0; }解析:枚举回文串的中间位置时要注意长度为奇数和偶数的处理方式是不一样的。
7题:编码实现求给定字符串(全为小写英文字母)的最小后继,如"abc"的最小后继为"abd","dhz"的最小后继为"di"。(Google笔试题)
#include <stdio.h> #include <string.h> #define MAXN 1024 int main(void) { char buf[MAXN]; int n, m, i; scanf("%s", buf); n = strlen(buf); for (i = n - 1; i >= 0; i--) { if (buf[i] + 1 <= 'z') { buf[i] += 1; buf[i + 1] = '