子串
有一些由英文字符组成的大小写敏感的字符串。请写一个程序,找到一个最长的字符串x,
使得:对于已经给出的字符串中的任意一个y,x或者是y的子串、或者x中的字符反序之
后得到的新字符串是y的子串。
输入:输入的第一行是一个整数t (1 <= t <= 10),t表示测试数据的数目。对于每一组测试
数据,第一行是一个整数n (1 <= n <= 100),表示已经给出n个字符串。接下来n行,每行
给出一个长度在1和100之间的字符串。
输出:对于每一组测试数据,输出一行,给出题目中要求的字符串x的长度;如果找不到
符合要求的字符串,则输出0。
代码
#include <stdio.h>
#include <string.h>
int t,n;
char str[100][101];
int searchMaxSubString(char* source) {
int subStrLen = strlen(source), sourceStrLen = strlen(source);
int i, j;
bool foundMaxSubStr;
char subStr[101], revSubStr[101];
while ( subStrLen > 0 ) {//搜索不同长度的子串,从最长的子串开始搜索
for (i = 0; i <= sourceStrLen - subStrLen; i++) {
//搜索长度为 subStrLen 的全部子串
strncpy(subStr, source+i, subStrLen);
strncpy(revSubStr, source+i, subStrLen);
subStr[subStrLen] = revSubStr[subStrLen] = '\0';
strrev(revSubStr);
foundMaxSubStr = true;
}
for(j=0; j<n; j++){
if ( strstr(str[j], subStr) == NULL && strstr(str[j], revSubStr) == NULL ) {
foundMaxSubStr = false;
break;
}
if (foundMaxSubStr) {
return(subStrLen);
}
subStrLen--;
}
return(0);
}
int main(){
int i, minStrLen, subStrLen;
char minStr[101];
scanf("%d", &t);
while(t--) {
scanf("%d", &n);
minStrLen= 100;
for (i = 0; i < n; i++) {//输入一组字符串
scanf("%s", str[i]);
if ( strlen(str[i]) < minStrLen ) {//寻找输入字符串中的最短字符串
strcpy(minStr, str[i]);
minStrLen = strlen(minStr);
}
}
subStrLen = searchMaxSubString(minStr);//搜索满足条件的最长字符串
printf("%d\n", subStrLen);
}
}
分析
(1)每输入一组字符串后,首先找到其中最短的字符串x0。然后根据x0搜索满足条件的子字符串。对x0的各子字符串从长到短依次判断是否满足条件,直到找到一个符合条件的子字符串为止。
(2) 搜索到x0的每个子字符串,并且根据子字符串的长度从长到短开始判断,不要遗漏。
总结
strlen: 计算字符串的长度
strncpy: 复制字符串的子串
strcpy: 复制字符串
strstr: 在字符串中寻找子字符串
strrev: 对字符串进行反序