用动态规划来代替KMP算法

package primary_class;
public class Test{
    //用动态规划来代替KMP算法,str1中是否含有str2,并且返回起始下标
    public static int search(String str1,String str2){
        if(str1==null||str1.length()<1||str2==null||str2.length()<1){
            return 0;
        }
        int m=str1.length();
        int n=str2.length();
        int[][] dp=new int[n][256];//n值表示的是状态的数目,也就是str2的长度,256表示的即将状态转换时当前遇到的字符,256是字符ASCII码的范围
        dp[0][str2.charAt(0)]=1;//表示当前状态是0,即还没有开始匹配,若遇到的字符是str2的第一个字符一样的字符,那么状态就会切换为1状态,否则状态保持在状态0
        int j=0;//当前的状态序号
        int x=0;//进行状态转移(或者说是状态回退)时的状态序号
        //dp数组只与str2有关,for循环求出dp[][]数组
        for(j=1;j<n;j++){//j值从状态1开始循环,前面初始条件已经考虑了状态0的情况
            for(int c=0;c<256;c++){
                dp[j][c]=dp[x][c];//这里先写出一般情况,若当前遇到的字符是任意字符c,那么状态转移到x状态,x状态是与j状态具有共同最长前缀的位置
            }
            dp[j][str2.charAt(j)]=j+1;//特殊情况也是最顺利的情况,若当前遇到的字符是与str2自身当前状态的字符一致的字符,那么就可以直接状态前移,不需要状态回退。即数组值也就是下一个状态就是j+1
            x=dp[x][str2.charAt(j)];//此外,还需要更新转移状态(辅助状态)的值,因为这个值在判断匹配的过程中也是变动的。更新x的思路与下面for循环中更新j状态值是一样的。假设当前状态 j 只有遇到 字符"C" 才能前移状态,变成j+1,若遇到除了"C"以外的字符,状态 j 会把这个字符委托给状态 X 处理,也就是 dp[j][其他字符] = dp[x][其他字符]:
        }
        //str2匹配str1的过程,利用到dp[][]
        j=0;//j值要重新初始化,开始匹配str1
        for(int k=0;k<m;k++){
            j=dp[j][str1.charAt(k)];//这一句会改变j值,改变j状态的思路与上面改变辅助状态x的思路是一致的
            if(j==n){//当状态到达了str2的末尾,则说明匹配结束,并且匹配成功
                return k-n+1;//返回str2在str1中的起始下标
            }
        }
        return -1;//str2不在str1中
    }
    public static void main(String[] args){
        String str1="absscdsdsd";
        String str2="sd";
        System.out.print(search(str1,str2));
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值