暴力子字符串查找算法

暴力子字符串查找算法的名字虽然很霸气,但是效率不是很高。是一种简单、粗暴的查找方式。
在最坏的情况下,暴力子字符串查找算法在长度为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;
                    }
                }
            }

        }

    }

}

运行结果打印:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值