zoukankan      html  css  js  c++  java
  • 算法笔记_061:蓝桥杯练习 字串统计(Java)

    目录

    1 问题描述

    2 解决方案

     


    1 问题描述

    问题描述
      给定一个长度为n的字符串S,还有一个数字L,统计长度大于等于L的出现次数最多的子串(不同的出现可以相交),如果有多个,输出最长的,如果仍然有多个,输出第一次出现最早的。
    输入格式
      第一行一个数字L。
      第二行是字符串S。
      L大于0,且不超过S的长度。
    输出格式
      一行,题目要求的字符串。

      输入样例1:
      4
      bbaabbaaaaa

      输出样例1:
      bbaa

      输入样例2:
      2
      bbaabbaaaaa

      输出样例2:
      aa
    数据规模和约定
      n<=60
      S中所有字符都是小写英文字母。
    提示
      枚举所有可能的子串,统计出现次数,找出符合条件的那个

    2 解决方案

    前三次提交只得了40分,只怪自己把KMP模式匹配算法写错了,冒汗...

    本题主要考查KMP模式匹配算法,思想比较简单,具体可以理解可以看注释哦

    具体代码如下:

    package com.liuzhen.systemExe;
    
    import java.util.Scanner;
    
    public class Main{
        //KMP算法求取next函数值
        public int[] getNext(char[] array) {
            int[] next = new int[array.length + 1];
            int j = 0;
            for(int i = 1;i < array.length;i++) {
                while(j > 0 && array[i] != array[j]) {
                    j = next[j];
                }
                if(array[i] == array[j]) {
                    j++;
                }
                next[i + 1] = j;
            }
            return next;
        }
        //使用KMP算法求取arrayB子串在arrayA中符合匹配的个数
        public int getKmpCount(char[] arrayA, char[] arrayB) {
            int count = 0;
            int[] next = getNext(arrayB);
            int j = 0;
            for(int i = 0;i < arrayA.length;i++) {
                while(j > 0 && arrayA[i] != arrayB[j]) {
                    j = next[j];
                }
                if(arrayA[i] == arrayB[j])
                    j++;
                if(j == arrayB.length) {
                    count++;
                    i = i - j + 1;   //此处是因为题目中说:不同的出现可以相交
                    j = 0;    
                }
            }
            return count;
        }
        //获取arrayA的开始位置为start长度L的子串
        public char[] getPartString(char[] arrayA, int start, int L) {
            char[] result = new char[L];
            int i = 0;
            while(i < L) {
                result[i++] = arrayA[start++]; 
            }
            return result;
        }
        //打印符合题意的子串
        public void printResult(String A, int L) {
            if(L <= 0 || L > A.length() || A.length() > 60 || A.equals(null))
                return;
            char[] arrayA = A.toCharArray();
            char[] max = getPartString(arrayA, 0, L);
            int maxCount = 1;
            while(L < arrayA.length) {
                for(int start = 0;start < arrayA.length - L;start++) {
                    char[] partA = getPartString(arrayA, start, L);
                    int tempCount = getKmpCount(arrayA, partA);
                    if(tempCount > maxCount || (tempCount == maxCount && partA.length > max.length)) {
                        maxCount = tempCount;
                        max = partA;
                    }
                }
                L++;
            }
            System.out.println(max);
        }
        
        public static void main(String[] args){
            Main test = new Main(); 
            Scanner in = new Scanner(System.in);
        //    System.out.println("请输入一个整数L和一个字符串A:");
            int L = in.nextInt();
            in.nextLine();
            String A = in.nextLine();
            test.printResult(A, L);
        }
    }

    运行结果:

    请输入一个整数L和一个字符串A:
    5
    bbaabaaaaabbbbbbbababaabaabaabbabababbbabbabbabbba
    baabaa
  • 相关阅读:
    skywalking物理拓扑图
    检测HTTPS证书到期时间
    docker zipkin 链路监控
    定时任务和任务-示例
    小程序列表循环出来的list是不同接口赋的值
    小程序编辑器报-50003错误肿么办?
    uni-app小程序组建
    2019
    春日
    Mac安装软件提示破损
  • 原文地址:https://www.cnblogs.com/liuzhen1995/p/6498791.html
Copyright © 2011-2022 走看看