做了一个问题突然想到可以用Kmp解决,所以看了一下自己之前写的关于Kmp的博客用JAVA实现的KMP匹配子串,记录一下,省的又忘了。

/*
*题目描述:
* 假定我们都知道非常高效的算法来检查一个单词是否为其他字符串的子串。
* 请将这个算法编写成一个函数,给定两个字符串s1和s2,请编写代码检查s2是否为s1旋转而成,要求只能调用一次检查子串的函数。
* 给定两个字符串s1,s2,请返回bool值代表s2是否由s1旋转而成。
* 字符串中字符为英文字母和空格,区分大小写,字符串长度小于等于1000。
*/

/*
*解题思路:
*
*方案1:
*分别比较字符串的原串和旋转串的前半段和旋转部分的后半段,两段都相同即返回true.
*时间复杂度为O(n2)
*
*方案2:
*假设原字符串有ABCD四个部分,旋转子串则有BCDA->CDAB->DABC->ABCD四种这四种都是ABCDABCD的子串,
*所以就将原问题转化为了判断新串是否是原串+原串的子串的问题.
*可以采用系统自带的contains函数或者kmp算法解决匹配子串的问题.
*/
解决代码如下:

  1. public int[] getNext(String str)
  2. {
  3. if(str == null || str.length() == 0)
  4. {
  5. return null;
  6. }
  7.  
  8. int strLen = str.length();
  9. int next[] = new int[strLen+1]; //next数组表示,长度为i的字符串最长公共前后缀的长度为next[i],所以需要多一个空间
  10. next[0] = next[1] = 0;
  11.  
  12. int j;
  13. for(int i = 1; i < strLen; i++)
  14. {
  15. j = next[i];
  16.  
  17. if(str.charAt(i) == str.charAt(j))
  18. {
  19. next[i+1] = next[i] + 1; //直接找到不用计算
  20. }
  21. else
  22. {//继续寻找next[next[i]]
  23. while(j > 0 && str.charAt(i) != str.charAt(j))
  24. {
  25. j = next[j]; //递归查找next[],直到找到字符相等或next[1];
  26. }
  27.  
  28. if(str.charAt(i) == str.charAt(j))
  29. {
  30. next[i+1] = next[j] + 1; //next
  31. }
  32. else
  33. {
  34. next[i+1] = 0;
  35. }
  36. }
  37. }
  38.  
  39. return next;
  40. }
  41.  
  42. public boolean findsubString(String originStr,String findStr,int next[])
  43. {
  44. if(originStr == null || findStr == null || originStr.length() == 0 || findStr.length() == 0)
  45. {
  46. return false;
  47. }
  48.  
  49. int matchLen = 0; //上一次已匹配的长度
  50. for(int i = 0; i < originStr.length(); i++)
  51. {
  52. if(originStr.charAt(i) == findStr.charAt(matchLen))
  53. {
  54. matchLen++;
  55. if(matchLen == findStr.length())
  56. {//找到子串
  57. return true;
  58. }
  59. }
  60. else
  61. {//通过next数组计算出findStr跳转的位置
  62. while(matchLen > 0 && originStr.charAt(i) != findStr.charAt(matchLen))
  63. {
  64. matchLen = next[matchLen];
  65. }
  66. }
  67. }
  68.  
  69. return false;
  70. }
  71.  
  72. public boolean checkReverseEqual(String s1, String s2)
  73. {
  74.  
  75. if(s1 == null || s2 == null)
  76. {
  77. return false;
  78. }
  79.  
  80. int oldLen = s1.length(),newLen = s2.length();
  81.  
  82. if(oldLen != newLen)
  83. {
  84. return false;
  85. }
  86.  
  87. String s3 = s1 + s1;
  88. int next[] = getNext(s2);
  89.  
  90. return findsubString(s3,s2,next);
  91.  
  92. /*
  93. 方法2
  94. String s3 = s1 + s1;
  95. return s3.contains(s2);
  96. */
  97.  
  98. /*
  99. 方法3
  100. int oldIndex;
  101. boolean flag = true;
  102.  
  103. for(int i = 0; i < oldLen; i++)
  104. {
  105. oldIndex = i;
  106. flag = true;
  107.  
  108. if(s1.charAt(i) == s2.charAt(0))
  109. {
  110. //比较旋转的前半段
  111. int newIndex;
  112. for(newIndex = 0; oldIndex + newIndex < oldLen; newIndex++)
  113. {
  114. if(s1.charAt(oldIndex + newIndex) != s2.charAt(newIndex))
  115. {
  116. flag = false;
  117. break;
  118. }
  119. }
  120.  
  121. if(flag == true)
  122. {
  123. //比较旋转的后半段
  124. for(int k = 0; k < oldIndex; k++)
  125. {
  126. if(s1.charAt(k) != s2.charAt(newIndex + k))
  127. {//newIndex + k防止新串不偏移
  128. flag = false;
  129. break;
  130. }
  131. }
  132. }
  133.  
  134. if(flag == true)
  135. {
  136. return true;
  137. }
  138. }
  139. }
  140. */
  141. }

还是把这道kmp的题po出来吧,省的以后自己也忘了的更多相关文章

  1. zstu.4194: 字符串匹配(kmp入门题&& 心得)

    4194: 字符串匹配 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 206  Solved: 78 Description 给你两个字符串A,B,请 ...

  2. HDU 1711 Number Sequence(KMP裸题,板子题,有坑点)

    Number Sequence Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  3. 51Nod 1277 字符串中的最大值(KMP,裸题)

    1277 字符串中的最大值 题目来源: Codility 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 一个字符串的前缀是指包含该字符第一个字母的连续子串,例如: ...

  4. poj-2406(kmp水题)

    题意:定义一个a*b=字符串a连接字符串b:给你一个字符串s,问你这个字符串最多能用多少个字符串t连接得到:例如:aaaa=4个a构成: 解题思路:kmp水题,next数组除了查找字串以外最广泛的一种 ...

  5. HDU 1711 - Number Sequence - [KMP模板题]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1711 Time Limit: 10000/5000 MS (Java/Others) Memory L ...

  6. POJ 3167 Cow Pattern ★(KMP好题)

    题意 给你一个数字序列S,再给一个数字序列pattern,S和pattern中的数字都是1到s(s<=25).每个序列里的数字都有个排名,也就是第几小,现在我们要用pattern来匹配S.在本题 ...

  7. 13-Oulipo(kmp裸题)

    http://acm.hdu.edu.cn/showproblem.php?pid=1686 Oulipo Time Limit: 3000/1000 MS (Java/Others)    Memo ...

  8. POJ Oulipo KMP 模板题

    http://poj.org/problem?id=3461 Oulipo Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4 ...

  9. POJ Oulipo(KMP模板题)

    题意:找出模板在文本串中出现的次数 思路:KMP模板题 #include<cstdio> #include<cstring> #include<cmath> #in ...

随机推荐

  1. 第10组 Beta冲刺(2/4)

    队名:凹凸曼 组长博客 作业博客 组员实践情况 童景霖 过去两天完成了哪些任务 文字/口头描述 编写商品主界面 展示GitHub当日代码/文档签入记录 暂无代码 接下来的计划 编写购买功能 还剩下哪些 ...

  2. Redis内存回收策略

    如果使用Redis的时候,不合理使用内存,把什么东西都放在内存里面,又不设置过期时间,就会导致内存的堆积越来越大.根据28法则,除了20%的热点数据之外,剩余的80%的非热点或不怎么重要的数据都在占用 ...

  3. 【Gamma阶段】第十次Scrum Meeting

    [Gamma阶段]第十次Scrum Meeting 每日任务内容 今日工作任务 明日待完成任务 完成人 准备测试质量保证的展示材料 准备测试展示视频 赵智源 修复热评的子评论BUG 准备前端技术展示材 ...

  4. MySQL5.7调优参数

    1. 更改MySQL Data File位置 datadir=/data/mysqlsocket=/data/mysql/mysql.sock 2. 调整OS参数 * soft nproc 10240 ...

  5. SQL 实现地区的实现树形结构递归查询(无限级分类),level为节点层级,由小至大依次

    //SQL 实现地区的实现树形结构递归查询(无限级分类),level为节点层级,由小至大依次 2018-09-25 StringBuilder areaSQL = new StringBuilder( ...

  6. 【06月18日】A股滚动市净率PB历史新低排名

    2010年01月01日 到 2019年06月18日 之间,滚动市净率历史新低排名. 上市三年以上的公司,2019年06月18日市净率在30以下的公司. 来源:A股滚动市净率(PB)历史新低排名. 1 ...

  7. 那些陌生的C++关键字

    C/C++中的关键字如下: 下面我们主要介绍一些比较陌生的关键字,一些常见的关键字这里就不再赘述了. 1.asm asm 是一个语句的分隔符,不能单独出现,必须接汇编指令.一组被大括号包含的指令或一对 ...

  8. kafka topic查看删除

    1,查看kafka topic列表,使用--list参数 >bin/kafka-topics.sh --zookeeper 127.0.0.1:2181 --list __consumer_of ...

  9. Java 并发-Unsafe 相关整理

    https://www.jianshu.com/p/2e5b92d0962e 1. Unsafe 类 Java 不能直接访问操作系统底层,而是通过本地方法来访问.Unsafe 类提供了硬件级别的原子操 ...

  10. windows上 nginx 配置代理服务,配置多域名,以及最简单实现跨域配置

    Nginx,不用多说啦,大家都熟悉的不能再熟悉了,它是一款轻量级的高性能Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,最近在本地研究将nginx和resin配合使用,使服务 ...