• 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去子串时,需要在所取子串的默认添加字符串结束符 ' '

  • 相关阅读:
    转游戏开发做的第一款手机网游的经历和体会
    cocos2d-x 单点事件用法
    cocos2d-x编译成android 以及android开发环境一些经验分享
    apk 反编译用法 mac上apktool
    cocos2d-x 中LUA和平台之间的函数调用理解
    项目经验
    sprintf 的基本用法
    html5标签 ----------- canvas vue / html
    vue 基于element组件库实现表格下多个子级展示
    vue基于proxy实现服务器反向代理功能
  • 原文地址:https://www.cnblogs.com/youxin/p/3242078.html
Copyright © 2020-2023  润新知