查找两个字符串a,b中的最长公共子串

该代码片段是用Java编写的,用于查找两个给定字符串的最长公共子串。程序首先比较字符串长度,然后使用一个HashMap来存储子串及其位置,通过遍历字符串计算最长公共子串,并优先输出较短字符串中先出现的子串。
摘要由CSDN通过智能技术生成

描述

查找两个字符串a,b中的最长公共子串。若有多个,输出在较短串中最先出现的那个。

注:子串的定义:将一个字符串删去前缀和后缀(也可以不删)形成的字符串。请和“子序列”的概念分开!

数据范围:字符串长度1≤length≤300 

进阶:时间复杂度: O(n3) ,空间复杂度: O(n) 

输入描述:

输入两个字符串

输出描述:

返回重复出现的字符

示例1

输入:

abcdefghijklmnop
abcsafjklmnopqrstuvw

输出:

jklmnop
import java.util.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNextLine()) { // 注意 while 处理多个 case
            String a = in.nextLine();
            String b = in.nextLine();
            getRes(a, b);
        }
    }

    public static void getRes(String s1, String s2) {
        if (s1.length() < s2.length()) {
            String tmp = s2; 
            s2 = s1;
            s1 = tmp;
        }
        char[] chs1 = s1.toCharArray();
        char[] chs2 = s2.toCharArray();
        int size1 = chs1.length;
        int size2 = chs2.length;
        Obj res = Obj.build(0, 0, true);
        for (int i=0; i<size1; i++) {
            String tmp = "";
            int count = 0;
            boolean lx = false;
            Map<Integer, Obj> map = new HashMap<>();
            for (int j=0; j<size2; j++) {
                Set<Map.Entry<Integer, Obj>> set = map.entrySet();
                for (Map.Entry<Integer, Obj> item : set) {
                    int k = item.getKey();
                    Obj v = item.getValue();
                    if (map.get(k).isJx && i+v.count<size1 && chs1[i+v.count] == chs2[j]) {
                        map.get(k).add(1);
                    }
                    else {
                        map.get(k).setIsJx(false);
                    }
                }
                if (chs1[i] == chs2[j]) {
                    map.put(j, Obj.build(1, j, true));
                }
            }

            Set<Map.Entry<Integer, Obj>> set = map.entrySet();
            for (Map.Entry<Integer, Obj> item : set) {
                int k = item.getKey();
                Obj v = item.getValue();
                if (v.isMore(res)) {
                    res = v;
                }
            }
        }

        System.out.println(s2.substring(res.start, res.start+res.count));
    }

    public static class Obj {
        int count;
        int start;
        boolean isJx;

        public static Obj build(int count, int start, boolean isJx) {
            Obj obj = new Obj();
            obj.count = count;
            obj.start = start;
            obj.isJx = isJx;
            return obj;
        }

        public boolean isMore(Obj o) {
            if (count > o.count) {
                return true;
            }
            if (count == o.count) {
                return start < o.start;
            }
            return false;
        }

        public void add(int i) {
            this.count += i;
        }

        public void setIsJx(boolean bool) {
            this.isJx = bool;
        }
    }

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值