sunday算法

sunday算法的概念如下:

Sunday算法是Daniel M.Sunday1990年提出的一种比BM算法搜索速度更快的算法。其核心思想是:在匹配过程中,模式串并不被要求一定要按从左向右进行比较还是从右向左进行比较,它在发现不匹配时,算法能跳过尽可能多的字符以进行下一步的匹配,从而提高了匹配效率。

假设在发生不匹配时S[i]≠T[j]1≤i≤N1≤j≤M。此时已经匹配的部分为u,并假设字符串u的长度为L。如图1。明显的,S[L+i+1]肯定要参加下一轮的匹配,并且T[M]至少要移动到这个位置(即模式串T至少向右移动一个字符的位置)

                 1 Sunday算法不匹配的情况

(1) S[L+i+1]在模式串T中没有出现。这个时候模式串T[0]移动到S[L+i+1]之后的字符的位置。如图2

        2 Sunday 算法移动的第 1 种情况

(2)S[L+i+1]在模式串中出现。这里S[L+i+1]从模式串T的右侧,即按T[M-1]T[M-2]…T[0]的次序查找。如果发现S[L+i+1]T中的某个字符相同,则记下这个位置,记为k1≤k≤M,且T[k]=S[L+i+1]。此时,应该把模式串T向右移动M-k个字符的位置,即移动到T[k]S[L+i+1]对齐的位置。如图3


依次类推,如果完全匹配了,则匹配成功 ; 否则,再进行下一轮的移动,直到 主串S 的待匹配长度小于模式串长度结束。

其算法实现如下,但只是最简单的实现,模式串中有重复字符会出错。

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner scanner=new Scanner(System.in);
		String total=scanner.nextLine();
		String sub=scanner.nextLine();
		int index=find(total,sub);
		System.out.println(index);
		scanner.close();
	}

	public static int find(String total, String sub) {
		int pos=0;
        int totalInc=0;
        int tLength=total.length();
        int sLength=sub.length();
		int[] temp=new int[256];
		for(int i=0;i<temp.length;i++){ //初始化
			temp[i]=-1;
		}
		for(int i=0;i<tLength;i++){
			for(int j=0;j<sLength;j++){
				char c=total.charAt(i);
				if(sub.charAt(j)==c&&temp[c]==-1){  //这里是求母串中的在模式串中从后往前
					temp[c]=sLength-j;        //数出现的位置,
					break;                       
				}
			}
		}
		while(pos<tLength-sLength+1){   //开始匹配
			int j=0;
			int i=pos;
			while(j<sLength){
				if(total.charAt(i)==sub.charAt(j)){
					i++;
					j++;
				}else{
					break;
				}
			}
			if(j==sLength)  //匹配成功
				return pos;
			else{
				int inc;
				char c=total.charAt(pos+sLength);
				if(temp[c]==-1)
				    inc=sLength+1;
				else
					inc=temp[c];
				totalInc+=inc;
				for(int k=0;k<totalInc;k++)  //输出一次尝试的结果
					System.out.print(" ");
				System.out.println(sub);
				pos=pos+inc;
			}
		}
		return -1;
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值