动态规划--求最长子串

最长不连续子串

伪代码实现

mcs(s1,s2)
//求最大不连续子串
int[][] states
//保存状态值,其中states[i][j]表示从s1[1...i]和s2[1,...j]的最大子串长度值
//子数组s1[0]表示空子串,初始 states[0][0]=0,表示空子串和空子串的最大子串长度为0
//例如:states[3][4]表示s1("12345")s2("12345")的子串,s1*("123")s2*("1234")的长度

for i=1 to s1.length+1
    for j=1 to s2.length+1
    if s1[i-1]==s2[j-1]
        states[i][j]=states[i-1][j-1]+1
    else
        states[i][j]=max(states[i][j-1],states[i-1][j])
    

java代码实现

public class TestC {
    public static void main(String[] args) {
        TestC c = new TestC();
        System.out.println(c.maxCommonSeq("xxsssxxsssasss","xxxsss"));
    }

    public String maxCommonSeq(String str1, String str2) {
        int[][] states = new int[str1.length() + 1][str2.length() + 1];

        for (int i = 1; i < states.length; i++) {
            char ch1 = str1.charAt(i - 1);
            for (int j = 1; j < states[i].length; j++) {
                char ch2 = str2.charAt(j - 1);
                if (ch1 == ch2)
                    states[i][j] = states[i - 1][j - 1] + 1;
                else
                    states[i][j] = Math.max(states[i][j - 1], states[i - 1][j]);
            }
        }

        out(states);

        int maxLen = states[states.length - 1][states[0].length - 1];
        StringBuilder sBuilder = new StringBuilder(maxLen);
        for (int i = states.length - 1, j = states[i].length - 1; i > 0 && j > 0;) {
            char ch1 = str1.charAt(i - 1);
            char ch2 = str2.charAt(j - 1);
            if (ch1 == ch2) {
                System.out.println(i + ", " + j);
                sBuilder.append(ch1);
                i--;
                j--;
            } else {
                if (states[i][j - 1] > states[i - 1][j])
                    j--;
                else
                    i--;
            }
        }
        sBuilder = sBuilder.reverse();
        return sBuilder.toString();
    }

    public void out(int[][] a) {

        for (int[] is : a) {
            for (int i : is) {
                System.out.print(i + " ");
            }
            System.out.println();
        }
        System.out.println();
    }
}

最长连续子串

伪代码

mcs(s1,s2)
//求最大连续子串
int[][] states

for i=1 to s1.length+1
    for j=1 to s2.length+1
    if s1[i-1]==s2[j-1]
        states[i][j]=states[i-1][j-1]+1
    else
        states[i][j]=0

java 代码实现

public class TestC {
    public static void main(String[] args) {
        TestC c = new TestC();
        System.out.println(c.maxCommonSeq("xxsssxxsssasss", "xxxsss"));
    }

    private class Point {
        int i;
        int j;
        int states;

        public Point(int i, int j, int states) {
            super();
            this.i = i;
            this.j = j;
            this.states = states;

        }

        @Override
        public String toString() {
            return "Point [i=" + i + ", j=" + j + ", states=" + states + "]";
        }

    }

    private List<String> find(List<Point> points, int max, String s1) {

        if (max == 0) {
            return null;
        }
        List<String> list = new ArrayList<>();

        StringBuilder sBuilder = new StringBuilder();

        for (int i = 0; i < points.size(); i++) {

            if (points.get(i).states == max) {

                for (int q = points.get(i).i - max; q < points.get(i).i; q++) {
                    sBuilder.append(s1.charAt(q));
                }
                list.add(sBuilder.toString());
                sBuilder = new StringBuilder();
            }
        }

        return list;
    }

    public List<String> maxCommonSeq(String str1, String str2) {
        int[][] states = new int[str1.length() + 1][str2.length() + 1];
        List<Point> points = new ArrayList<>();
        int max = 0;
        for (int i = 1; i < states.length; i++) {
            char ch1 = str1.charAt(i - 1);
            for (int j = 1; j < states[i].length; j++) {
                char ch2 = str2.charAt(j - 1);
                if (ch1 == ch2) {
                    states[i][j] = states[i - 1][j - 1] + 1;
                    max = Math.max(max, states[i][j]);
                    points.add(new Point(i, j, states[i][j]));
                } else {
                    states[i][j] = 0;
                }

            }
        }

        return find(points, max, str1);
    }

}

转载于:https://my.oschina.net/u/3706181/blog/1605228

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值