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);
}
}