【算法设计与分析基础】19、字符串匹配算法

package cn.xf.algorithm.ch07inputEnhancement;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.junit.Test;

/**
 *
 * 功能:字符串匹配算法,(还有一种叫KMP算法的,也是很经典的算法,就是比较复杂)
 *
 * 第一步:对于给定的长度为m的模式和在模式文本中用到的字母表,按照上面的描述构造移动表
 * 第二步:将模式与文本的开始处对齐
 * 第三步:重复代码中过程,知道发现一个匹配子串或者模式到达了文本的最后一个字符以外。从模式的最后一个字符开始,比较模式和文本中的相应字符,直到:要么所有m个字符都匹配(然后停止),要么遇到了一对不匹配的字符。
 * 在后一种情况下,如果c是当前文本中和模式的最后一个字符相对齐的字符,从移动表的第c列中取出单元格t(c)的值,然后将模式沿着文本向右移动t(c)个字符的距离
 *
 * @author xiaofeng
 * @date 2017年7月23日
 * @fileName Horspool.java
 *
 */
public class Horspool {

	/**
	 * 生成字母表map数据表
	 * @return
	 */
	public Map<Character, Integer> getLetterTable(char model[], char special[]) {
		//创建对应的键值对
		Map result = new HashMap<Character, Integer>();
		//吧所有的字母填进去
		for(int i = 97, j = 65; i < 123 || j < 91; ++i,++j) {
			result.put((char)i, model.length);
			result.put((char)j, model.length);
		}
		//把排除在外的特殊字符添加进去
		for(int i = 0; i < special.length; ++i) {
			result.put(special[i], model.length);
		}

		//吧给定的串加入字段表
		for(int i = 0; i < model.length; ++i) {
			//向右边需要移动的长度是模型长度减去当前位置然后在根据0开始的数组原因,这里需要减1,正好把这个移动到对应的位置
			result.put(model[i], model.length - i - 1);
		}

		return result;
	}

	public int horspoolMatching(char model[], char main[], char special[]) {
		//比对model在main中是否有完全一样的子串,反馈字符串起始的位置
		//1、生生需要位移的字母映射表
		Map shiftTable = this.getLetterTable(model, special);
		//2、从model模板的最右开始比较
		int i = model.length - 1;
		//3、循环遍历母串,直到匹配成功,或者到末尾,没有匹配子串
		while(i < main.length) {
			int haveMatched = 0; //已经匹配到的字符,用来推算下一个比较字符的位置
			//当比较的个数还没有完全比较完,也即是个数比model长度小,并且当前字符和母串匹配,则继续循环比较
			while(haveMatched < model.length && main[i - haveMatched] == model[model.length - 1 - haveMatched]) {
				++haveMatched; //继续比较下一个
			}

			//如果比较OK的长度正好和model一样,说明比较成功,否则回移
			if(haveMatched == model.length) {
				return i - model.length + 1;
			} else {
				//否则回移,这里的回移根据字母表的位置回退
				int shifIndex = (Integer) shiftTable.get(main[i - haveMatched]);
				i = i + shifIndex;
			}
		}

		//循环结束
		return -1;
	}

	@Test
	public void testMatch() {
		char model[] = {‘C‘, ‘U‘, ‘T‘, ‘T‘, ‘E‘, ‘R‘};
		char special[] = {‘_‘, ‘$‘};
		char main[] = {‘A‘, ‘a‘, ‘_‘, ‘$‘, ‘U‘, ‘T‘, ‘T‘, ‘E‘, ‘R‘, ‘g‘, ‘C‘, ‘U‘, ‘T‘, ‘T‘, ‘C‘, ‘U‘, ‘T‘, ‘T‘, ‘E‘, ‘R‘};
		Horspool horspool = new Horspool();
		Map result = horspool.getLetterTable(model, special);
		int result1 = horspool.horspoolMatching(model, main, special);
		System.out.println(result1);
	}

	@Test
	public void testzimu() {
		char model[] = {‘C‘, ‘U‘, ‘T‘, ‘T‘, ‘E‘, ‘R‘};
		char special[] = {‘_‘, ‘$‘};
		Horspool horspool = new Horspool();
		Map result = horspool.getLetterTable(model, special);
		System.out.println(result.toString());
	}

	@Test
	public void test() {
		int a = ‘a‘; //97
		int z = ‘z‘; //122
		int A = ‘A‘; //65
		int Z = ‘Z‘; //90
		char a1 = 97;
		System.out.println(a1);
	}
}

  

时间: 2024-12-25 01:13:49

【算法设计与分析基础】19、字符串匹配算法的相关文章

算法设计与分析基础(第3版)读书笔记(及几处翻译上的错误~~)

算法设计与分析基础(第3版) p16 in-place翻译为'在位'?'就地'更合适点 p38 amortized应翻译为'均摊','摊销'这个词简直莫名其妙(可能因为翻译是做算法交易导致的?) p64 迭代优于递归(迭代始终是增量式的,而递归就没办法增量了,除非能够dump整个运行时栈) p73 通过算法可视化得到一个更好的非递归算法(人的图像认知直觉思维?) p79 验证一个拓扑是环.星.还是团?(这个地方有点意思,因为我想到了动态的Verify) p87 凸包问题:从数据结构上讲,Set<

【算法设计与分析基础】大整数乘法

#include<iostream> #include<string> #include<time.h> #include<stdlib.h> #include<sstream> using namespace std; class BigDecimal{ private: int max(int a,int b){//获取两数中的最大值 return a^((a^b) & -(a<b)); } public: string n;

【算法设计与分析基础】关灯游戏

① R.java  用于存储一些全局变量 package lightoff; public class R { /* public static int lightCondition[][] = { {1,0,0,1,1}, {1,0,0,1,1}, {1,0,0,1,1}, {1,0,0,1,1}, }; */ public static int lightCondition[][] = { {1,1,1,1}, {1,1,1,1}, {1,1,1,1}, {1,1,1,1}, }; //灯面

【算法设计与分析基础】16、高斯消元法

package cn.xf.algorithm.ch06ChangeRule; import java.util.ArrayList; import java.util.List; import org.junit.Test; import cn.xf.util.GenericPair; /** * * 功能:高斯消元法,也就是多元数据矩阵,依次吧每列的其他行数据消去为0,然后求出一个元的解,然后就可以根据这个数据来递推出其他元的解 * @author xiaofeng * @date 2017

【算法设计与分析基础】20、动态规划-硬币搜集问题

题目: 在n*m格木板中放有一些硬币,每格的硬币数目最多为一个.在木板左上方的一个机器人需要搜集尽可能多的硬币并把他们带到右下方的单元格,每一步,机器人可以从当前的位置向右移动一格 或者向下移动一格,当机器人遇到一个有硬币的单元格的时,就会将这枚硬币搜集起来 解题: 硬币收集的时候,我们 从结果状态开始看,当搜集当前硬币的时候,只有两种方式,从上往下搜集,或者从左向右搜集 也就是当前f[i,j] = max{f[i, j - 1], f[i - 1, j]},初始化第一行和第一列,从第二行和列开

【算法设计与分析基础】17、堆

以数组来存放堆数据 package cn.xf.algorithm.ch06ChangeRule; import java.util.ArrayList; import java.util.List; import org.junit.Test; /** * * 功能:堆的构造 * 1.堆可以定义为一颗二叉树,树的节点包含键,并且满足一下条件 * 1) 树的形状要求:这棵二叉树是基本完备的(完全二叉树),树的每一层都是满的,除了最后一层最右边的元素可能缺位 * 2) 父母优势,堆特性,每一个节点

【算法设计与分析基础】18、霍纳法则

产生随机数 package cn.xf.algorithm.ch02; import java.util.ArrayList; import java.util.List; /** * 生产随机数 * @author xiaof * */ public class Random { /** * 生产一个随机数的数列 * @param n 生成n个数列 * @param m 数据在0和m-1之间 * @param seed 随机初始种子 * @param a 参数 * @param b 参数 *

【算法设计与分析基础】23、堆排序-2

package cn.xf.algorithm.ch09Greedy.util; import java.util.ArrayList; import java.util.List; /** * 堆构造以及排序 * * .功能:堆的构造 * 1.堆可以定义为一颗二叉树,树的节点包含键,并且满足一下条件 * 1) 树的形状要求:这棵二叉树是基本完备的(完全二叉树),树的每一层都是满的,除了最后一层最右边的元素可能缺位 * 2) 父母优势,堆特性,每一个节点的键都要大于或者等于他子女的键(对于任何叶

【算法设计与分析基础】14、快速排序

package cn.xf.algorithm.ch04; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.junit.Test; public class QuikSort { public int hoarePartition(List data, int left, int right) { //当要比对的数据相差为1的时候,表示就只有一条数据要进行比较了 if(d