编程之美3-1:字符串移位包含问题.

题目:

  给定两个字符串s1和s2,要求判断s2是否被包含在s1或者通过s1循环移位的串.比如s1="ABCD",s2="CDA".很显然符合.而s1="ABCD",S2="CBA".则不符合.

解法:

  法一:很容易想到的方法是直接枚举法.即依次找到s2的各个循环移位并且同时判断是否包含在s1中.strstr函数可以满足判断字串判断.代码:

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
char s1[]="AABCD";
char s2[]="CDA";
int main(){
    int len,i,j;
    char tempchar;
    len=strlen(s1);
    for(i=0;i<len;i++){                   //一共len次循环次数
        tempchar=s1[0];
        for(j=0;j<len-1;j++)         //进行循环移位
            s1[j]=s1[j+1];
        s1[len-1]=tempchar;
        if(NULL!=strstr(s1,s2)){   //如果再s1中找到了s2返回1
            return 1;
        }
    }
    return 0;                                  //如果都没找到,返回0
}    

这个解法简单好想,但是问题很明显就是效率问题.要知道如果给的字符串非常的长,那么想必运行时间会加大.

解法2:

  这个题目有个隐含条件就是s1的长度应该是一定比s2的长.否则可以直接判断不存在题目所说的那种可能.再看一下s1循环移位的结果:

    AABCD---ABCDA---BCDAA---CDAAB---DAABC---AABCD

  其实可以发现如果把我们连接第1项与第6项可以得到AABCDAABCD.再看看可以知道所有AABCD的移位字串都包含在AABCDAABCD中.所以可以直接判断s2是否包含在s1是中来判断是否包含在s1的循环移位串当中.AABCDAABCD任何一个字串都可以通过s1的字串或者s1循环移位后的字串得到.这一点保证了这个算法的正确性.

#include "stdio.h"
#include "string.h"
#include "malloc.h"
char s1[]="AABCD";
char s2[]="CAD";
int main(){
    int len,i;
    char *s;
    len=strlen(s1);
    printf("%d
",sizeof(s1));
    s=(char*)malloc(sizeof(s1)*2-1);    //分配2倍s1的空间用于保存AABCDAABCD
    for(i=0;i<len;i++)                    //赋值给s开始
        s[i]=s1[i];
    for(i=len;i<len*2;i++)
        s[i]=s1[i-len];
    s[i]='';                            //赋值给s结束.要给s字符串加''!!!
    if(strstr(s,s2)!=NULL)    
        printf("true");
    else
        printf("false");
    free(s);
}

这里同样有个问题是当字符串非常的长的时候那么必然带来了空间的问题.所以这个算法等于是用空间来换时间的.空间与时间往往很难同时满足,只有按照特定情况取舍.但是明显算法二的算法要好很多.

  

原文地址:https://www.cnblogs.com/brillliu/p/3550716.html