http://poj.grids.cn/practice/2744

描述
现在有一些由英文字符组成的大小写敏感的字符串,你的任务是找到一个最长的字符串x,使得对于已经给出的字符串中的任意一个y,x或者是y的子串,或者x中的字符反序之后得到的新字符串是y的子串。
输入
输入的第一行是一个整数t (1 <= t <= 10),t表示测试数据的数目。对于每一组测试数据,第一行是一个整数n (1 <= n <= 100),表示已经给出n个字符串。接下来n行,每行给出一个长度在1和100之间的字符串。
输出
对于每一组测试数据,输出一行,给出题目中要求的字符串x的长度。

这道题我刚开始认为很复杂,以为很难。但看了答案后才知道这题很简单。没有什么特殊的技巧。

问题分析:

假设x0是输入的字符串中最短的一个,x是所要找的字符串,x'是x反序后得到的字符串,显示,要么x是x0的子串,要么x' 是x0的子串,隐藏,只要取出x0的每个子串x,判断x是否满足给定的条件,找到其中最长的子串即可。

思路:先找出最短的字符串,然后利用最短字符串从长到短产生搜索子串,然后进行匹配检测,难点应该是从长到短产生搜索子串时不能有遗漏..

刚开始提交时compile error,提示

error: ‘strrev’ was not declared in this scope
去看了下vs下面的警告。

warning C4996: 'strrev': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _strrev. See online help for details.
1> d:\program files\visual studio\vc\include\string.h(250) : 参见“strrev”的声明

strrev有些编译器可能不支持,用标准的,前面加一个_即可。

要熟练的使用几个字符串处理函数:

char * strncpy(char *dest, char *src,size_tnum);

har *strstr(char *str1, char *str2);
功能:从字符串str1中查找是否有字符串str2,如果有,从str1中的str2位置起,返回str1中str2起始位置的指针,如果没有,返回null。
返回值:返回该位置的指针,如找不到,返回空指针。

char *strrev( char *str);

strrev(str) reverses all characters in str(except for the terminating null ). Returns a pointer to the reversed string.

最开始看到strrev有点奇怪,传递的是指针,而且函数确实改变了str,没必要在传一个同样的返回值。感觉没什么必要。但函数

原型就是如此。

#include<stdio.h>
#include<string.h> int t,n;
char str[][]; int searchMaxSubString(char *source)
{
int subStrLen,sourceStrLen;
subStrLen=sourceStrLen=strlen(source);
int i,j;
bool found;
char subStr[],revSubStr[];
while(subStrLen>) //搜索不同长度的子串时,从最长的子串开始搜索
{
for(i=;i<=sourceStrLen-subStrLen;i++)
{
strncpy(subStr,source+i,subStrLen);
strncpy(revSubStr,source+i,subStrLen);
subStr[subStrLen]=revSubStr[subStrLen]='\0'; //很重要的,否则结果错误 _strrev(revSubStr); found=true;
for(j=;j<n;j++)
{
if(strstr(str[j],subStr)==NULL && strstr(str[j],revSubStr)==NULL)
{
found=false;
break;
}
}
if(found)
return subStrLen;
}
subStrLen--;
}
return ;
} int main()
{
int minStrLen;
char minStr[]; scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
minStrLen=;//每次必须重置
for(int i=;i<n;i++)
{
scanf("%s",str[i]);
if(strlen(str[i])<minStrLen)
{
strcpy(minStr,str[i]);
minStrLen=strlen(str[i]);
}
}
int ret=searchMaxSubString(minStr);
printf("%d\n",ret);
}
}

可以参考http://www.cnblogs.com/ns517/archive/2009/01/22/1380048.html,这个答案不好理解。

常见错误:

再用strncpy去子串时,需要在所取子串的默认添加字符串结束符 ' \0 '

pojg2744找一个最长的字符串x,使得对于已经给出的字符串中的任意一个y,x或者是y的子串,或者x中的字符反序之后得到的新字符串是y的子串。的更多相关文章

  1. JAVA判断指定url地址是否匹配指定url集合中的任意一个

    判断字符串为空和判断集合是否为空用到依赖,也可以改成自己的方式 <!-- Spring Web --> <dependency> <groupId>org.spri ...

  2. 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 例如 a b c e s f c s a d e e 矩阵中包含一条字符串"bccced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中

    // test20.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> #include< ...

  3. 在SQLSERVER里,怎么让别人只能输入一个字母的约束该怎么写?就是26个字母中的任意一个?

    alter table 表名 add constraint ck_char check(自段名 like '[a-z]' or 自段名 like '[A-Z]')

  4. 检查一个string是否包含List<string>中的任意一个

    bool b = listOfStrings.Any(s=>myString.Contains(s)); 应用在where子句中的示例: //获取路径 var groupPaths = grou ...

  5. VIM 用正则表达式,非贪婪匹配,匹配竖杠,竖线, 匹配中文,中文正则,倒数第二列, 匹配任意一个字符 :

    VIM 用正则表达式 批量替换文本,多行删除,复制,移动 在VIM中 用正则表达式 批量替换文本,多行删除,复制,移动 :n1,n2 m n3     移动n1-n2行(包括n1,n2)到n3行之下: ...

  6. js 空正则匹配任意一个位置

    看一个正则 这里明显,起到匹配作用的是 | 后的,可 | 后什么都没有,原理不知道,也没有搜到文献,只有在 Reg101 上是这样解释的, 所以得出结论: js 中,空正则匹配任意一个位置. 不过,这 ...

  7. 给一个非常长的字符串str 另一个字符集比方{a,b,c} 找出str 里包括{a,b,c}的最短子串。要求O(n)

    给一个非常长的字符串str 另一个字符集比方{a,b,c} 找出str 里包括{a,b,c}的最短子串.要求O(n). 比方,字符集是a,b,c,字符串是abdcaabcx,则最短子串为abc. 设置 ...

  8. 4.写一个控制台应用程序,接收一个长度大于3的字符串,完成下列功能: 1)输出字符串的长度。 2)输出字符串中第一个出现字母a的位置。 3)在字符串的第3个字符后面插入子串“hello”,输出新字符串。 4)将字符串“hello”替换为“me”,输出新字符串。 5)以字符“m”为分隔符,将字符串分离,并输出分离后的字符串。 */

    namespace test4 {/* 4.写一个控制台应用程序,接收一个长度大于3的字符串,完成下列功能: 1)输出字符串的长度. 2)输出字符串中第一个出现字母a的位置. 3)在字符串的第3个字符 ...

  9. 编写一个类,其中包含一个排序的方法Sort(),当传入的是一串整数,就按照从小到大的顺序输出,如果传入的是一个字符串,就将字符串反序输出。

    namespace test2 { class Program { /// <summary> /// 编写一个类,其中包含一个排序的方法Sort(),当传入的是一串整数,就按照从小到大的 ...

随机推荐

  1. MyEclipse 8.5整合Git,并在Github上发布项目(转)

    下载Eclipse的git插件——EGit.下载网址http://download.eclipse.org/egit/updates-1.3/org.eclipse.egit-updatesite-1 ...

  2. android点滴之PendingIntent的使用

    一概念 PendingIntent就是一个能够在满足一定条件下运行的Intent,它相比于Intent的优势在于自己携带有Context对象.这样他就不必依赖于某个activity才干够存在. 它和I ...

  3. GDB学习之道:GDB调试精粹及使用实例

    一:列文件清单  1. List  (gdb) list line1,line2 二:执行程序  要想运行准备调试的程序,可使用run命令,在它后面可以跟随发给该程序的任何参数,包括标准输入和标准输出 ...

  4. SQL 语言划分

    从功能上划分,SQL 语言能够分为DDL,DML和DCL三大类. 1. DDL(Data Definition Language)     数据定义语言,用于定义和管理 SQL 数据库中的全部对象的语 ...

  5. 感觉挺有意思的SQL题目

    1.有如下数据,要求查询每个班最低分和最高分,并将最高分与最低分显示为同一列 ID Student CourseName Score1 张三 English 802 张三 Math 703 张三 Ch ...

  6. [C/C++基础]读写文件

    1.打开.关闭文件: FILE* fp = fopen(string.c_str(), FLAG); string.c_str():需用C语言字符串形式: FLAG说明: r: 只读方式打开: w: ...

  7. BZOJ 1664: [Usaco2006 Open]County Fair Events 参加节日庆祝( dp )

    先按时间排序( 开始结束都可以 ) , 然后 dp( i ) = max( dp( i ) , dp( j ) + 1 ) ( j < i && 节日 j 结束时间在节日 i 开 ...

  8. Appium+Python app自动化测试之脚本启动和停止Appium服务

    研究了一段时间的Appium android app的自动化测试,工作中需要连接多台手机终端同时执行测试用例,我实现的方式是获取用例中需要执行用例的设备id个数以及实际连接到的设备数(通过adb de ...

  9. HYSBZ 2301

    /*** 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数 **/ #include <iost ...

  10. Log Collect

    http://ossectools.blogspot.com/2011/03/comprehensive-log-collection.html https://www.hacking-lab.com ...