子串次数——类似KMP

 

老规矩  先来看问题   字符串a  在A中出现了多少次   

求次数    。

 当然有很多种算法  最简单的  一个一个找呗   不过这种太麻烦  我们不讲这种   

 

 

我在写这个算法的时候  用到了KMP算法的部分内容   

 

  public static void Getnext(int next[],char[] t)
  {
    int j=0,k=-1;
    next[0]=-1;
    while(j<t.length)
    {
      if((k == -1) || (t[j] == t[k]))
      {
        j++;k++;
        next[j] = k;
      }
      else k = next[k];//此语句是这段代码最反人类的地方,如果你一下子就能看懂,那么请允许我称呼你一声大神!
    }
  }

上面这段就借鉴了(有改动) (其余都是原创)
当然 这里最难理解的就是这段 相信你如果能很透彻的理解这一段 下面的代码对你就是小儿科。


我就不举例说明这段代码的作用了 这段代码是求某段字符串和从总字符串的开头的相识度的 也就是有几个字符是连续重复的。
记住 必须是连续着的相同

我们不是要求子串在母串中出现的次数吗 我们这里能求出从开头开始的相识度 那这样理解 如果开头就是我们的子串 那么 是不是就好办了

主要讲解就到这这里


具体方法看代码


提示一下 要考虑到母串开头就是只要两者的有个子串的情况


个人认为这样算会比暴力破解的方法好点
当然还可以进行改进 可以在求相识度的过程中就得出次数
有兴趣的可以对代码进行改进或重新编码尝试一下。


 


import java.util.Scanner; public class Substring_Number {


  public static int count = 0;

  public static void main(String[] argv) {

    Scanner in = new Scanner(System.in);
    String  A=in.nextLine();//输入母串
    String a=in.nextLine();//输入子串
    A=a+A;
    int[] n=new int[A.length()+1];
    Getnext(n,A.toCharArray());
    int sum=0;
    int i;
    int cont=1;
    for (i=a.length()-1;i<A.length();i++){
      if(n[i+a.length()]-n[i+a.length()]==a.length()){
        cont++;
        i+=a.length()-1;
      }
      if(i+a.length()>=A.length()){
        break;
      }
    }
    for(i=a.length()-1;i<A.length()-a.length()+1;i++){
      if(n[i]%a.length()==0){
        if(n[i+a.length()]-n[i]==a.length() && n[i+a.length()]<=cont*a.length()){
          sum++;
//          i+=a.length();
        }
      }
    }
    System.out.println(sum);
  }
  public static void Getnext(int next[],char[] t)
  {
    int j=0,k=-1;
    next[0]=-1;
    while(j<t.length)
    {
      if((k == -1) || (t[j] == t[k]))
      {
        j++;k++;
        next[j] = k;
      }
      else k = next[k];//此语句是这段代码最反人类的地方,如果你一下子就能看懂,那么请允许我称呼你一声大神!
    }
  }

}

代码就在这里 

 

如果哪位发现有什么问题 或不对的地方  烦请予以指正。

 

   

posted @ 2020-03-26 16:13  Mr小明同学  阅读(263)  评论(0编辑  收藏  举报