字符串移位包含问题

参考了http://kenby.iteye.com/blog/1451910

http://blog.csdn.net/sunnyyoona/article/details/25918163

有时候看编程之美里面的算法题,觉得他们怎么能够想到这么精妙的idea.

字符串移位包含问题

题目

给定两个字符串 s1 和 s2, 要求判定 s2 是否能够被通过 s1 作循环移位 ( rotate )

得到的字符串包含. 例如, 给定 s1 = AABCD 和 s2 = CDAA, 返回 true; 给定

s1 = ABCD 和 s2 = ACBD, 返回 false.


1.暴力的方法,

每次不断的移位s1,判断s2是否在s1中

这种方法效率很低


2.从规律出发

以S1 = ABCD为例,先分析对S1进行循环移位之后的结果,如下所示:
ABCD--->BCDA---->CDAB---->DABC---->ABCD……
假设我们把前面的移走的数据进行保留,会发现有如下的规律:
ABCD--->ABCDA---->ABCDAB---->ABCDABC---->ABCDABCD……
因此,可以看出对S1做循环移位所得到的字符串都将是字符串S1S1的子字符串。如果S2可以由S1循环移位得到,那么S2一定在S1S1上,这样时间复杂度就降低了

在http://blog.csdn.net/sunnyyoona/article/details/25918163中给出了代码。

注意其中的strcat函数。


3.还可以折中的想法。

单独每次拿s1中的一个字符和s2中的一个字符进行比较。如果相等两者就往后移(s1可以循环,所以要对s1的长度取余),如果不相等,就s1跳到下一位,而s2从0开始。代码如下。

  1. int main()  
  2. {  
  3.     char src[] = "AEBBCD";  
  4.     char des[] = "CDAE";  
  5.   
  6.     int len_src = strlen(src);  
  7.     int len_des = strlen(des);  
  8.     int i, j, k;  
  9.   
  10.     for (i = 0; i < len_src; i++) {  
  11.         j = i;  
  12.         k = 0;  
  13.         while (src[j] == des[k]) {  
  14.             j = (j + 1) % len_src;  
  15.             k++;  
  16.         }  
  17.         if (k == len_des) {  
  18.             printf("Yes\n");  
  19.             getchar();  
  20.             return 1;  
  21.         }  
  22.     }  
  23.     printf("No\n");  
  24.     getchar();  
  25.     return 0;  
  26. }  
这和字符串的匹配很相似,就是kmp的暴力法,这样子我在想是否可以在kmp的基础上对这个问题在进行优化了?

参照暴力解发的代码


int main()  
 {  
     char src[] = "AEBBCD";  
     char des[] = "AFB";  
   
     int len_src = strlen(src);  
     int len_des = strlen(des);  
     int i=0, j=0;  
   
     while((i<len_src)&&(j<len_des)) {  
         if(src[i]==des[j])
 {
 i=(++i)%len_src;
 j++;
 }
 else
 {
 j=0;
 if((i-j+1+len_src)>len_src)
 break;
 i=(i-j+1+len_src)%len_src;
 
}
 
    }  
 
if(j==len_des)
 printf("yes\n");
 if(j<len_des)
 printf("No\n");  
 
    return 0;  
 } 
 


 

我觉得kmp的next方法可以参照过来用,但是可能问题在于判断边界,即何时跳出



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
O1709字符串移位包含问题是给定两个字符串s1和s2,要判断s2是否可以通过对s1进行循环移位得到的字符串包含。根据给出的引用内容,可以有以下方法来解决这个问题: 1. 使用最直接的方法:对s1进行循环移位,并判断移位后的字符串是否包含s2。 2. 使用空间换时间的方法:将s1的所有循环移位得到的字符串保存在一个集合中,然后判断s2是否在这个集合中。 根据题目描述,输入是两个字符串,中间由单个空格隔开,字符串包含字母和数字,长度不超过30。输出是一个布尔值,表示是否可以通过循环移位得到的字符串包含。例如,对于输入"AABCD CDAA",输出为true。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [字符串移位包含问题](https://blog.csdn.net/li1914309758/article/details/82192743)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [[补档][C++习题]字符串移位包含问题](https://blog.csdn.net/LQL_114514/article/details/130785813)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值