4.4子串

问题定义:

有一些由英文字符组成的大小写敏感的字符串。请写一个程序,找到一个最长的字符串x,使得:对于已经给出的字符串中的任意一个y,x或者是y的子串、或者x中的字符反序之后得到的新字符串是y的子串。


输入:输入的第一行是一个整数t (1 <= t <= 10),t表示测试数据的数目。对于每一组测试
数据,第一行是一个整数n (1 <= n <= 100),表示已经给出n个字符串。接下来n行,每行给出一个长度在1和100之间的字符串。


输出:对于每一组测试数据,输出一行,给出题目中要求的字符串x的长度;如果找不到符合要求的字符串,则输出0。


输入样例
2
3
ABCD
BCDFF
BRCD
2
rose
orchid


输出样例
2
2


问题分析
假设x0是输入的字符串中最短的一个,x是所要找的字符串,x'是x反序后得到的字符串。显然,要么x是x0的子串、要么x'是x0的子串。因此,只要取出x0的每个子串x,判断x是否满足给定的条件,找到其中满足条件的最长子串即。


解决方案
每输入一组字符串后,首先找到其中最短的字符串x0。然后根据x0搜索满足条件的子字符串。对x0的各子字符串从长到短依次判断是否满足条件,直到找到一个符合条件的子字符串为止。此问题的关键有两点:
(1)
搜索到x0的每个子字符串,并且根据子字符串的长度从长到短开始判断,不要遗漏了任何子字符串。
(2) 熟练掌握下列几个字符串处理函数,确保程序代码简洁、高效。
strlen:计算字符串的长度


strncpy:复制字符串的子串


strcpy:复制字符串


strstr:在字符串中寻找子字符串


strrev:对字符串进行反序

此乃字符串处理的典型例题,不知到为什么在Ubuntu下提示没有strrev函数,可能是编译器的问题吧。

代码如下:

/* * *Declaration:The author of <<Accelerated C++>> has wrote in the end of that book: As you look for reading materimal, keep in mind that books on the shelf do not make you a better programmer. Ultimately, the only way to improve your programming is to write programs. >这些程序来自一些ACM书籍,作者只为提高编程能力,实现书中例题或练习。如有侵权,请联系作者,作者将立即删除。 * *联系邮箱:mingxinglai#gmail.com * */ /* 熟练掌握下列几个字符串处理函数,确保程序代码简洁,高效 strlen: 计算字符串的长度 strncpy:复制字符串的字串 strcpy:复制字符串 strstr:在字符串中寻找子串 strrev:对字符串进行反顺序 */ #include <stdio.h> #include <string.h> int t, n; char str[100][101]; char * strrev( char *p) { int strLen = strlen(p); int i = 0; char temp; for( i = 0; i < strLen / 2; i++) { temp = p[i]; p[i] = p[ strLen - i -1]; p[strLen - i - 1] = temp; } return p; } 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++) { 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 argc, char* argv[]) { 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( str[i] ); } } subStrLen = searchMaxSubString( minStr ); printf("%d\n", subStrLen); } return 0; }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值