做了一个问题突然想到可以用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算法解决匹配子串的问题.
*/
解决代码如下:

public int[] getNext(String str)
{
if(str == null || str.length() == 0)
{
return null;
} int strLen = str.length();
int next[] = new int[strLen+1]; //next数组表示,长度为i的字符串最长公共前后缀的长度为next[i],所以需要多一个空间
next[0] = next[1] = 0; int j;
for(int i = 1; i < strLen; i++)
{
j = next[i]; if(str.charAt(i) == str.charAt(j))
{
next[i+1] = next[i] + 1; //直接找到不用计算
}
else
{//继续寻找next[next[i]]
while(j > 0 && str.charAt(i) != str.charAt(j))
{
j = next[j]; //递归查找next[],直到找到字符相等或next[1];
} if(str.charAt(i) == str.charAt(j))
{
next[i+1] = next[j] + 1; //next
}
else
{
next[i+1] = 0;
}
}
} return next;
} public boolean findsubString(String originStr,String findStr,int next[])
{
if(originStr == null || findStr == null || originStr.length() == 0 || findStr.length() == 0)
{
return false;
} int matchLen = 0; //上一次已匹配的长度
for(int i = 0; i < originStr.length(); i++)
{
if(originStr.charAt(i) == findStr.charAt(matchLen))
{
matchLen++;
if(matchLen == findStr.length())
{//找到子串
return true;
}
}
else
{//通过next数组计算出findStr跳转的位置
while(matchLen > 0 && originStr.charAt(i) != findStr.charAt(matchLen))
{
matchLen = next[matchLen];
}
}
} return false;
} public boolean checkReverseEqual(String s1, String s2)
{ if(s1 == null || s2 == null)
{
return false;
} int oldLen = s1.length(),newLen = s2.length(); if(oldLen != newLen)
{
return false;
} String s3 = s1 + s1;
int next[] = getNext(s2); return findsubString(s3,s2,next); /*
方法2
String s3 = s1 + s1;
return s3.contains(s2);
*/ /*
方法3
int oldIndex;
boolean flag = true; for(int i = 0; i < oldLen; i++)
{
oldIndex = i;
flag = true; if(s1.charAt(i) == s2.charAt(0))
{
//比较旋转的前半段
int newIndex;
for(newIndex = 0; oldIndex + newIndex < oldLen; newIndex++)
{
if(s1.charAt(oldIndex + newIndex) != s2.charAt(newIndex))
{
flag = false;
break;
}
} if(flag == true)
{
//比较旋转的后半段
for(int k = 0; k < oldIndex; k++)
{
if(s1.charAt(k) != s2.charAt(newIndex + k))
{//newIndex + k防止新串不偏移
flag = false;
break;
}
}
} if(flag == true)
{
return true;
}
}
}
*/
}

还是把这道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. [解决方案]IIS常见问题集锦

    内容 地址 更新时间 IIS7如何实现访问HTTP跳转到HTTPS访问 https://www.cnblogs.com/xiefengdaxia123/p/8542737.html 2019-10-1 ...

  2. Lab7:同步互斥

    并发进程的正确性 独立进程 不和其他进程共享资源或状态 确定性 -> 输入状态决定结果 可重现 -> 能够重现起始条件 调度顺序不重要 并发进程 在多个进程间有资源共享 不确定性 不可重现 ...

  3. [转帖]Redis持久化--Redis宕机或者出现意外删库导致数据丢失--解决方案

    Redis持久化--Redis宕机或者出现意外删库导致数据丢失--解决方案 https://www.cnblogs.com/xlecho/p/11834011.html echo编辑整理,欢迎转载,转 ...

  4. (一)pdf的数据类型

    引自:https://blog.csdn.net/steve_cui/article/details/81912528 pdf的数据类型主要由8种 boolean(布尔型)        :关键字为“ ...

  5. 小知识点 之 JVM -XX:SurvivorRatio

    JVM参数之-XX:SurvivorRatio 最近面试过程中遇到一些问JVM参数的,本着没用过去学习的办法看了些博客写得不准确,参考oracle的文档记录一下,争取每天记录一点知识点 -XX:Sur ...

  6. Python做一个计时器的动画

    一.问题在做连连看的时候需要加一个计时器的动画,这样就完成了计时功能的设计. 二.解决主要思路: 1.先产生一个画布,用深颜色填充满. 2.产生一个新的矩阵用来覆盖画布,背景用白色,就可以渲染出来递减 ...

  7. Java学习:字符串概述与特点

    字符串概述与特点 java.lang.String类 代表字符串 API当中说:Java程序中的所有字符串字面值(如“abc“)都作为此类的实例实现.其实就是说:程序当中所用的双引号字符串,都是Str ...

  8. 爬虫框架之selenium

    Selenium 一.概述 Web自动化测试工具,可以运行在浏览器,根据指令操作浏览器 只是工具,必须与第三方浏览器结合使用 安装: Linux:sudo pip3 install selenium ...

  9. .net平台下对C#代码的编译

    最近赶项目忽然想到一个问题,那就是在 .Net平台下的C#代码是怎么从源代码到机器可以识别的电脑的(只怪自己上学不好好读书,现在又要重补一遍了!!!) 话不多说直接上调研结果: 预习知识: 1: IL ...

  10. 为什么要用 redis 而不用 map 做缓存?

    缓存分为本地缓存和分布式缓存.以 Java 为例,使用自带的 map 或者 guava 实现的是本地缓存,最主要的特点是轻量以及快速,生命周期随着 jvm 的销毁而结束,并且在多实例的情况下,每个实例 ...