zoukankan      html  css  js  c++  java
  • 【算法设计与分析基础】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);
    	}
    }
    

      

  • 相关阅读:
    软件开发者路线图 从学徒到高手 读后感
    Greplin:搜索你的所有在线社交内容
    黄小琥 / 简单/不简单 / 没那么简单
    讯雷 云系列 不错
    来自Amazon、Cloudera、Microsoft与IBM的HadoopasaService
    FAQs and feedback
    I've Never Been To Me by Charlene with lyrics
    烧香网 历害
    4A公司
    一个新的比较网站,做的不错
  • 原文地址:https://www.cnblogs.com/cutter-point/p/7260784.html
Copyright © 2011-2022 走看看