1. 回朔法:在字符串查找的时候最容易想到的是暴力查找,也就是回朔法。其思路是将要寻找的串的每个字符取出,然后按顺序在源串中查找,如果找到则返回true,否则源串索引向后移动一位,再重复查找,直到找到返回true,或者源串查找完也没有找到返回false;这种方法简单粗暴,但思路清晰。又因为每次查找失败,源串需要回到起始位置的下一个位置开始查找,所以该算法也称为回朔法。
  2. KMP算法:先对要查找的字符串进行分析,找出其中重复的子字符串。然后将目标串与源串比较,一旦比较失败,则不用回朔,而是根据目标串子串的重复情况,直接调到重复子串的下一个位置。这样减少了大量的回朔,算法复杂度得意大量减小。

下面代码演示了回朔法和KMP算法,并作测试。

KMP算法查找:

 package org.lyk.impl;

 public class KMP<T>
{
public boolean comtains(T[] source, T[] target) throws Exception
{
if(source == null || target == null)
{
throw new Exception("比较目标不能为空");
} int sourceLength = source.length;
int targetLength = target.length;
if(targetLength > sourceLength)
//目标串长达大于源串,肯定不存在,直接返回false
return false;
else if(targetLength == sourceLength)
{
//两个串长度相等,则挨个比较,若发现任何一个元素不相等,则直接返回false,若所有元素均相等个,则返回true
return this.compair(source, target);
}
else
{//源串长度大于目标串长度,用KMP算法比较 //分析目标串的重复情况,生成next数组
int[] next = this.getNext(target);
int currentSourceIndex = ;
int currentTargetIndex = ; //如果目标串没有到末尾,则继续循环,如果已经到目标串末尾,则说明找到
while(currentTargetIndex < targetLength)
{
//如果源串下标越界,说明查找结束,乜没有找到结果,返回false
if(currentSourceIndex >= sourceLength)
return false; if(source[currentSourceIndex].equals(target[currentTargetIndex]))
{
//两个元素相等,目标串和源串下标向后各移动一位
currentSourceIndex++;
currentTargetIndex++;
}
else
{ //目标串的第一个元素就与源串不相等,则源串向后移动一个位置继续比较
if(currentTargetIndex == )
{
currentSourceIndex++;
} currentTargetIndex = next[currentTargetIndex];
}
}
return true;
}
} private int[] getNext(T[] target)
{
int[] next = new int[target.length];
if(next.length > )
{
for(int i = ; i<target.length; i++)
{
int count = ;
for(int j = ;j < i-; j++)
{
boolean flag = true;
for(int k = ; k <= j; k++)
{
if(target[k] != target[i--j+k])
{
flag = false;
break;
}
}
if(flag == true)
{
count = j+;
}
}
next[i] = count;
}
}
return next;
} private boolean compair(T[] source, T[]target)
{
for(int i = ; i < source.length; i++)
{
if(!source[i].equals(target))
return false;
}
return true;
}
}

回朔法(暴力比较)查找字符串:

 public static boolean strContain_BF(String _source, String _target)
{
boolean retVal = false;
if (null == _source || null == _target || "".equals(_source) || "".equals(_target))
return false;
char[] source = _source.toCharArray();
char[] target = _target.toCharArray();
int sourceLength = source.length;
int targetLength = target.length;
if (targetLength > sourceLength)
return false;
else if (targetLength == sourceLength)
{
for (int i = ; i < sourceLength; i++)
{
if (source[i] != target[i])
return false;
}
return true;
} else
{
for (int i = ; i <= sourceLength - targetLength; i++)
{
boolean flag = true;
for (int j = ; j < targetLength; j++)
{
if (target[j] != source[i + j])
{
flag = false;
break;
}
}
if (flag == true)
return true;
}
return false;
}
}

回朔法/KMP算法-查找字符串的更多相关文章

  1. KMP算法查找字符串

    假设长字符串为t,短字符串为p.为了进行KMP匹配,首先需要计算字符串p的next数组,后面实现了计算该数组的函数void KmpGenNext(char* p, int* next).对于”abca ...

  2. 数据结构与算法--KMP算法查找子字符串

    数据结构与算法--KMP算法查找子字符串 部分内容和图片来自这三篇文章: 这篇文章.这篇文章.还有这篇他们写得非常棒.结合他们的解释和自己的理解,完成了本文. 上一节介绍了暴力法查找子字符串,同时也发 ...

  3. 【剑指offer12】矩阵中的路径(回朔法),C++实现

    1.题目 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子.如果一条路径经过了矩阵中 ...

  4. 基于KMP算法的字符串模式匹配问题

    基于KMP算法的字符匹配问题 反正整个清明都在纠结这玩意...差点我以为下个清明要给自己过了. 至于大体的理解,我就不再多说了(还要画图多麻烦鸭),我参考了以下两个博客,写的真的不错,我放了超链接,点 ...

  5. 51NOD 1292 1277(KMP算法,字符串中的有限状态自动机)

    在前两天的CCPC网络赛中...被一发KMP题卡了住了...遂决定,哪里跌倒就在哪里爬起来...把个KMP恶补一发,连带着把AC自动机什么的也整上. 首先,介绍设定:KMP算法计划解决的基本问题是,两 ...

  6. KMP算法 (字符串的匹配)

    视频参考 对于正常的字符串模式匹配,主串长度为m,子串为n,时间复杂度会到达O(m*n),而如果用KMP算法,复杂度将会减少线型时间O(m+n). 设主串为ptr="ababaaababaa ...

  7. KMP算法在字符串中的应用

    KMP算法是处理字符串匹配的一种高效算法 它首先用O(m)的时间对模板进行预处理,然后用O(n)的时间完成匹配.从渐进的意义上说,这样时间复杂度已经是最好的了,需要O(m+n)时间.对KMP的学习可以 ...

  8. 字符串匹配算法之————KMP算法

    上一篇中讲到暴力法字符串匹配算法,但是暴力法明显存在这样一个问题:一次只移动一个字符.但实际上,针对不同的匹配情况,每次移动的间隔可以更大,没有必要每次只是移动一位: 关于KMP算法的描述,推荐一篇博 ...

  9. 字符串匹配的KMP算法详解及C#实现

    字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串"ABCDABD" ...

随机推荐

  1. PHP使用libevent实现高性能httpServer

    今天发现php也有一个libevent的扩展,安装后尝试下了一个webserver(httpserver), 发现性能还不错,逻辑很简单,每秒响应速度1800~4000次/s 代码如下 <?ph ...

  2. ASP.NET MVC中的拦截器

    在ASP.NET MVC中,有三种拦截器:Action拦截器.Result拦截器和Exception拦截器, 所谓的拦截器也没有什么的,只是写一个类,继承另一个类和一个接口,顺便实现接口里面的方法而以 ...

  3. DMZ区域

    DMZ是英文"demilitarized zone"的缩写,中文名称为"隔离区",也称"非军事化区".它是为了解决安装防火墙后外部网络不能访 ...

  4. unity, 读写xls

    可以用npoi: http://npoi.codeplex.com/ 把npoi.dll放在unity里即可. 读取代码: using System.IO;using NPOI.SS.UserMode ...

  5. HTML 图像

    通过使用 HTML,可以在文档中显示图像. 实例 插入图像 本例演示如何在网页中显示图像. 从不同的位置插入图片 本例演示如何将其他文件夹或服务器的图片显示到网页中. (可以在本页底端找到更多实例.) ...

  6. windows p12(pfx)个人证书安装过程

    证书库个人证书存储区为其中的每个证书维护一个属性CERT_KEY_PROV_INFO_PROP_ID,该属性指定了证书对应的密钥容器的相关信息,包括密钥容器名,CSP名称,CSP类型,密钥用途,以及C ...

  7. CERT_KEY_CONTEXT_PROP_ID,CERT_KEY_PROV_INFO_PROP_ID,CERT_KEY_PROV_HANDLE_PROP_ID和CERT_KEY_SPEC_PROP_ID

    上面四个属性是CertSetCertificateContextProperty或CertGetCertificateContextProperty可以为证书上下文设置的几个属性,下面对它们的关联简单 ...

  8. 剑指offer系列34----按之字形顺序打印二叉树

    [题目]请实现一个函数按照之字形打印二叉树, * 即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印, * 其他行以此类推. 未优化,不是最优解,博主用的是队列 ...

  9. android学习笔记21——消息提示Toast

    消息提示可细分为两种:大量消息提示——当程序有大量图片.信息需要展示时,采用对话框消息提示: 小量消息提示——当程序只有少量信息需要呈现给用户时,采用轻量级的对话框——Toast; Toast ==& ...

  10. visual studio 声明数组太大,导致栈溢出

    在解释原因前我们先看一下一个由C/C++编译的程序占用的内存分为几个部分: 1.栈区(stack segment):由编译器自动分配释放,存放函数的参数的值,局部变量的值等.在Windows下,栈是向 ...