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

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 filesvisual studiovcincludestring.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[100][101];

 

int searchMaxSubString(char *source)
{
    int subStrLen,sourceStrLen;
    subStrLen=sourceStrLen=strlen(source);
    int i,j;
    bool found;
    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]=''; //很重要的,否则结果错误

             _strrev(revSubStr);
             
            found=true;
            for(j=0;j<n;j++)
            {
                if(strstr(str[j],subStr)==NULL && strstr(str[j],revSubStr)==NULL)
                {
                    found=false;
                    break;
                }
            }
            if(found)
                return subStrLen;
        }
        subStrLen--;
    }
    return 0;
}

int main()
{
    int minStrLen;
    char minStr[101];
     
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        minStrLen=101;//每次必须重置
        for(int i=0;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
",ret);
    }
}

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

常见错误:

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

原文地址:https://www.cnblogs.com/youxin/p/3242078.html