暴力子字符串查找算法的名字虽然很霸气,但是效率不是很高。是一种简单、粗暴的查找方式。
在最坏的情况下,暴力子字符串查找算法在长度为N的文本中查找长度为M的模式需要~NM次字符比较。
核心思想:就是对主串中的每一个字符作为子串的开头,与要匹配的字符串进行匹配。对大串做大循环,每个字符开头做子串的长度的小循环,知道匹配成功或者全部遍历完成为止。
package com.test.test;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* 暴力子字符串查找算法 2015年10月24日 下午6:21:09
*
* @author 张耀晖
*
*/
public class Test5 {
public static void main(String[] args) {
Test5 test = new Test5();
int index = test.searchFirst("hhh", "wohhhxiaohhhhhhhhh");
System.out.println("目标字符串第一次出现的索引位置:" + index);
List<Integer> list = test.searchTotal("hhh", "wohhhxiaohhhhhhhhh");
System.out.print("目标字符串出现的所有的索引位置:");
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
System.out.print(iterator.next() + ", ");
}
}
/**
* 查询目标字符串在总字符串中第一次出现的索引位置
*
* @param pat
* 目标字符串
* @param txt
* 总字符串
* @return 所要查询的字符串第一次出现的索引位置,如果索引为-1就说明不存在。
*/
public int searchFirst(String pat, String txt) {
int index = -1;// 索引
int txtLength = txt.length();// 总字符串的长度
int patLength = pat.length();// 所要查询的字符串的长度
for (int i = 0; i <= txtLength - patLength; i++) {// 控制总字符串比较位置
for (int j = 0; j < patLength; j++) {// 控制所要查询的字符串的比较位置
if (txt.charAt(i + j) != pat.charAt(j)) {// 在比较中如果有不同的字符就跳出该循环,继续从总字符串的下一个字符开始比较
break;
} else {
if (j == patLength - 1) {// 如果整个目标字符串的内容与总字符串中的内容完全匹配,就返回目标字符串第一次出现的索引位置
index = i;
return i;
}
}
}
}
return index;
}
/**
* 查询目标字符串在总字符串中出现的所有的索引位置
*
* @param pat
* 目标字符串
* @param txt
* 总字符串
* @return 保存有查询出来的所有目标字符串在总字符串中出现的索引位置
*/
public List<Integer> searchTotal(String pat, String txt) {
int txtLength = txt.length();// 总字符串的长度
int patLength = pat.length();// 所要查询的字符串的长度
List<Integer> list = new ArrayList<Integer>();
// for (int i = 0; i <= txtLength-patLength; i++) {
//
// for (int j = 0; j < patLength; j++) {
// if(pat.charAt(j)!=txt.charAt(i+j)){
// break;
// }else{
// if(j==(patLength-1)){
// list.add(i);
// break;
// }
// }
// }
//
// }
// return list;
mSearch(pat, txt, patLength, txtLength, 0, list);// 为了实现递归将循环判断比较的内容抽取成一个方法
return list;
}
/**
*
* @param pat
* 目标字符串
* @param txt
* 总字符串
* @param patLength
* 目标字符串的长度
* @param txtLength
* 总字符串的长度
* @param index
* 目标字符串开始的比较位置
* @param list
* 用于存储匹配到的目标字符串在总字符串中的索引位置
*/
public void mSearch(String pat, String txt, int patLength, int txtLength,
int index, List<Integer> list) {
for (int i = index; i <= txtLength - patLength; i++) {
for (int j = 0; j < patLength; j++) {
if (pat.charAt(j) != txt.charAt(i + j)) {
break;
} else {
if (j == patLength - 1) {
list.add(i);
index = i + patLength;// 修改之后查询的总字符串比较位置,防止出现把目标字符串不作为整体看待的情况
mSearch(pat, txt, patLength, txtLength, index, list);// 递归
return;
}
}
}
}
}
}
运行结果打印: