zoukankan      html  css  js  c++  java
  • 最长重复子串和首次出现的位置

    Problem Description:
    给定一个字符串,找出其中最长的重复出现的字符串,并且给出其首次出现的位置。
    输入
    输入包含多组测试数据;
    每组测试字符串占一行。
    
    数据保证:
    50%的字符串长度在[0,100],
    100%的字符串长度[0,1000]。
    输出
    对于每组测试数据,请输出最长的重复出现的字符串和其首次出现的位置。
    每组输出占一行,格式为:首次出现位置 最长的重复字符串,中间用空格分隔。
    如果没有重复字符串,输出-1。
    
    样例输入
    abcdefg
    yetfgvyabcdabjcabcsdfeg
    yetfabc defhjihjabc defyy
    样例输出
    -1 
    7 abc
    4 abc def

    解题思路:

             原字符串 -> 后缀数组 -> 备份后缀数组 -> 对后缀数组排序 -> 对排序后的数组,两两比较相邻元素,找到其最长公共前缀子串,并记录最大长度和下标 -> 组合出最长重复子串内容,并由备份后缀数组,求出首次出现的位置。

    Java 代码:

    import java.util.Arrays;
    import java.util.Scanner;
    
    public class Main {
        public String find(String str){     
            int len = str.length();
            String[] array = new String[len];
            for(int i = 0; i < str.length(); i++) { // 产生后缀数组
                array[i] = str.substring(i);
            }
            String[] copyArray = new String[len];
            System.arraycopy(array, 0, copyArray, 0, array.length); // 备份排序前的数组元素。
            Arrays.sort(array);
            int max = 0;
            int index = 0;
            for (int i = 0; i < array.length-1; i++) { // 两两比较相邻的字符串,找到最长共同前缀子串
                String tmp1 = array[i];
                String tmp2 = array[i+1];
                int count = 0;
                for (int j = 0; j < tmp1.length() && j < tmp2.length(); j++) {
                    if(tmp1.charAt(j) == tmp2.charAt(j)) {
                        count++;
                        if(count > max) {
                            max = count;
                            index = i;
                        }
                    } else { //不是共同前缀时,跳出循环
                        break;
                    }
                }
            }
            if(max == 0)
                return "-1";
            else {
                StringBuilder sb = new StringBuilder();
                String tmp = array[index].substring(0, max); //找到最大重复子串的内容
                for (int i = 0; i < copyArray.length; i++) { // 找到最大重复子串在排序前的数组中元素的前缀的下标
                    if (copyArray[i].startsWith(tmp)) {
                        sb.append(i);
                        break;
                    }
                }
                sb.append(" ");
                sb.append(tmp);
                return sb.toString(); //返回结果
            }
        }
        public static void main(String[] args) throws Exception{
            Scanner cin = new Scanner(System.in);
            while (cin.hasNext()) {
                String str = cin.nextLine();
                String result = new Main().find(str);
                System.out.println(result);
            }
            cin.close();
        }
    }
  • 相关阅读:
    初始Openwrt
    Angular CLI 使用教程指南参考
    Visual Studio Code怎么在同一窗口打开多个项目文件?
    mysql查看数据表是否有重复数据
    Angular UI框架 Ng-alain @delon的脚手架的生成开发模板
    VS2010 WDK7.1.0 Win7_64
    Nodejs使用TLS
    python定时执行方法
    Visual Studio Code 使用Git进行版本控制
    VSCode中设置Python解释器和pylint的波浪线问题
  • 原文地址:https://www.cnblogs.com/lasclocker/p/4881127.html
Copyright © 2011-2022 走看看