字符串循环移位包含

时间:2023-01-03 21:21:39

题目:

      给定两个字符串S1,S2,要求判断是否通过S1循环移位可以得到S2,比如说:S1 = AABCD,S2 = CDAA,结果返回true。给定S1=ABCD和S2=ACBD,结果返回false。

 

方法1:

      最简单的就是将S1循环一遍,每一次都是将S1循环右移一位,然后和S2进行比较。效率低到O(len(S1)*len(S2)).

代码:

#include "stdafx.h"
#include<iostream>
#include<stdio.h>
#include<time.h>
#include<math.h>
#include<stdlib.h>
#include<algorithm>
#include<queue>
#include<Windows.h>
using namespace std;
//O(len(s1)*len(s2))
#define MAX 100
char s1[MAX];
char s2[MAX];
//测试是否符合题意
bool test()
{
 int len1=strlen(s1);
 int len2=strlen(s2);
 //每次将s1循环右移一位
 for(int i=0;i<len1;i++)
 {
  char t=s1[len1-1];
  //循环右移的话从尾向前比较方便,循环左移的话从头到尾比较方便
  for(int i=len1-2;i>=0;i--)
  {
   s1[i+1]=s1[i];
  }
  s1[0]=t;
  //进行比较
  if(strstr(s1,s2)!=NULL)
  {
   return true;
  }
 }
 return false;
}
int _tmain(int argc, _TCHAR* argv[])
{
 while(cin>>s1>>s2)
 {
  if(test())
  {
   cout<<"true"<<endl;
  }
  else
  {
   cout<<"false"<<endl;
  }
 }

 ::system("pause");
 return 0;
}

 

方法2:

     以S1=ABCD为例,分析s1的循环移位得到的结果,如下所示:

    ABCD->BCDA->CDAB->DABC->ABCD->.....

     假设我们把前面移走的数据进行保留,会发现有如下规律:
     ABCD-> ABCDA-> ABCDAB->ABCDABC->ABCDABCD


   这里,我们可以发现,实际对s1的循环移位得到的字符串实际为s1s1。只需要判断s1s1中是否含有s2即可

代码:

#include "stdafx.h"
#include<iostream>
#include<stdio.h>
#include<time.h>
#include<math.h>
#include<stdlib.h>
#include<algorithm>
#include<queue>
#include<Windows.h>
using namespace std;
#define MAX 100
char s1[MAX];
char s2[MAX];
char s3[MAX*2];
//测试是否符合题意
bool test()
{
 int len1=strlen(s1);
 int len2=strlen(s2);
 strcpy(s3,s1);
 strcpy(s3+len1,s1);
 if(strstr(s3,s2)!=NULL)
 {
  return true;
 }
 return false;
}
int _tmain(int argc, _TCHAR* argv[])
{
 while(cin>>s1>>s2)
 {
  if(test())
  {
   cout<<"true"<<endl;
  }
  else
  {
   cout<<"false"<<endl;
  }
 }

 ::system("pause");
 return 0;
}