LCS与图算法

11 篇文章 0 订阅
求两个字符串最长公共子串的问题。大体解法是用一个矩阵来记录两个字符串中所有位置的两个字符之间的匹配情况,若是匹配则为1,否则为0。然后求出对角线最长的1序列,其对应的位置就是最长匹配子串的位置.

package graph;   
  
/**  
 * @author B.Chen  
 */  
public class LCS {   
  
    /**  
     * @param a  
     * @param b  
     * @return lcs string  
     */  
    public String lcs(String a, String b) {   
        if (a.length() == 0 || b.length() == 0) {   
            return "";   
        }   
        int[][] matrix = new int[a.length() + 1][b.length() + 1];   
        for (int i = 0; i < a.length() + 1; i++) {   
            matrix[i][0] = 0;   
        }   
        for (int i = 0; i < b.length() + 1; i++) {   
            matrix[0][i] = 0;   
        }   
        String[] arrayA = a.split("");   
        String[] arrayB = b.split("");   
        int maxloop = 0;   
        int position = 0;   
        for (int i = 1; i < a.length() + 1; i++) {   
            for (int j = 1; j < b.length() + 1; j++) {   
                if (arrayA[i - 1].equals(arrayB[j - 1])) {   
                    matrix[i][j] = matrix[i - 1][j - 1] + 1;   
                    if (matrix[i][j] > maxloop) {   
                        maxloop = matrix[i][j];   
                        position = i;   
                    }   
                } else {   
                    matrix[i][j] = 0;   
                }   
            }   
        }   
        StringBuffer result = new StringBuffer();   
        if (maxloop == 0) {   
            return "";   
        }   
        for (int i = position - maxloop; i < position; i++) {   
            result.append(arrayA[i]);   
        }   
        return result.toString();   
    }   
  
    /**  
     * @param a  
     * @param b  
     * @return int lcs length  
     */  
    public int maxLength(String a, String b) {   
        String length = lcs(a, b);   
        return length.length();   
    }   
  
}  




package graph;   
  
public class GraphNode {   
    public GraphNode link;   
    public int info;   
}  
package graph;   
  
public class GraphList {   
  
    public GraphNode first;   
    public GraphNode last;   
    public boolean visitable;   
    public int getAjd(int[] ajd) {   
        GraphNode current = first;   
        int length = 0;   
        while(current != null) {   
            ajd[length++] = current.info;   
            current = current.link;   
        }   
        return length;   
    }   
    public void addNode(int v) {   
        GraphNode node = new GraphNode();   
        node.info = v;   
        if(first == null) {   
            first = node;   
            last = node;   
        } else {   
            last.link = node;   
            last = node;   
        }   
    }   
}  
package graph;   
  
/**  
 * @author B.Chen  
 *  
 */  
public class Graph {   
  
    /**  
     * 节点数  
     */  
    private int length;   
  
    /**  
     * 链表  
     */  
    private GraphList[] list;   
  
    /**  
     * 权集  
     */  
    private int[][] weight;   
       
    /**  
     * 轻边集  
     */  
    private int[][] lightSide;   
       
    /**  
     * 等价类  
     */  
    private int[] replaceValue;   
  
    /**  
     * @param length  
     */  
    public Graph(int length) {   
        this.length = length;   
        list = new GraphList[length];   
        weight = new int[length][length];   
        lightSide = new int[length][length];   
        replaceValue = new int[length];   
        for(int i=0;i<length;i++) {   
            replaceValue[i] = i;   
            for(int j=0;j<length;j++) {   
                weight[i][j] = 9999;   
            }   
        }   
    }   
  
    /**  
     * @param v  
     */  
    public void dfs(int v) {   
        int[] ajd = new int[length];   
        int ajdlength = list[v].getAjd(ajd);   
        list[v].visitable = true;   
        System.out.print(v + " ");   
        for (int i = 0; i < ajdlength; i++) {   
            int w = ajd[i];   
            if (!list[w].visitable) {   
                dfs(w);   
            }   
        }   
    }   
  
    /**  
     * 深度优先遍历     
     */  
    public void dfsTravel() {   
        for (int i = 0; i < length; i++) {   
            list[i].visitable = false;   
        }   
        for (int i = 0; i < length; i++) {   
            if (!list[i].visitable) {   
                dfs(i);   
            }   
        }   
    }   
  
    /**  
     * 广度优先遍历   
     */  
    public void bfsTravel() {   
        for (int i = 0; i < length; i++) {   
            list[i].visitable = false;   
        }   
        bfs();   
    }   
  
    /**  
     * bfs  
     */  
    private void bfs() {   
        Queue queue = new Queue();   
        for (int index = 0; index < length; index++) {   
            if (!list[index].visitable) {   
                queue.addQueue(index);   
                list[index].visitable = true;   
                System.out.print(index + " ");   
                while (!queue.isEmpty()) {   
                    int temp = queue.front();   
                    queue.deleteQueue();   
                    int[] adj = new int[length];   
                    int ajdlength = list[temp].getAjd(adj);   
                    for (int i = 0; i < ajdlength; i++) {   
                        int w = adj[i];   
                        if (!list[w].visitable) {   
                            System.out.print(w + " ");   
                            queue.addQueue(w);   
                            list[w].visitable = true;   
                        }   
                    }   
                }   
            }   
  
        }   
    }   
  
    /**  
     * 长度     
     */  
    public void length() {   
        System.out.println(length);   
    }   
  
    /**  
     * @return boolean  
     */  
    public boolean isEmpty() {   
        return length == 0;   
    }   
  
    /**  
     * @param info  
     */  
    public void addGraph(int info) {   
        for (int i = 0; i < length; i++) {   
            if (list[i] == null) {   
                GraphList g = new GraphList();   
                g.addNode(info);   
                list[i] = g;   
                break;   
            }   
        }   
    }   
  
    /**  
     * 添加有向图的一条边  
     * @param vfrom  
     * @param vto  
     * @param value 权  
     */  
    public void addSide(int vfrom, int vto, int value) {   
        list[vfrom].addNode(vto);   
        weight[vfrom][vto] = value;   
    }   
  
    /**  
     * 添加无向图的一条边  
     * @param vfrom  
     * @param vto  
     * @param value  
     */  
    public void addDoubleSide(int vfrom, int vto, int value) {   
        list[vfrom].addNode(vto);   
        list[vto].addNode(vfrom);   
        weight[vfrom][vto] = value;   
        weight[vto][vfrom] = value;   
    }   
  
    /**  
     * 打印图     
     */  
    public void print() {   
        for (int i = 0; i < length; i++) {   
            GraphNode current = list[i].first;   
            while (current != null) {   
                System.out.print(current.info + " ");   
                current = current.link;   
            }   
            System.out.println();   
        }   
    }   
  
    /**  
     * Dijkstra  
     *   
     * @param v  
     * @return int[]  
     */  
    public int[] shortPath(int v) {   
        int[] shortPath = new int[length];   
        boolean[] weightFound = new boolean[length];   
        for (int i = 0; i < length; i++) {   
            // 趋近无穷   
            shortPath[i] = 9999;   
            weightFound[i] = false;   
        }   
        shortPath[v] = 0;   
        weightFound[v] = true;   
        Queue queue = new Queue();   
        queue.addQueue(v);   
        while (!queue.isEmpty()) {   
            int temp = queue.front();   
            queue.deleteQueue();   
            int[] ajd = new int[length];   
            int ajdlength = list[temp].getAjd(ajd);   
            for (int i = 0; i < ajdlength; i++) {   
                int w = ajd[i];   
                if (!weightFound[w]) {   
                    if (shortPath[w] > shortPath[temp] + weight[temp][w]) {   
                        shortPath[w] = shortPath[temp] + weight[temp][w];   
                    }   
                }   
            }   
            int minWeightNode = 0;   
            for (int i = 0; i < length; i++) {   
                if (!weightFound[i]) {   
                    minWeightNode = i;   
                    for (int j = 0; j < length; j++) {   
                        if (!weightFound[j]) {   
                            if (shortPath[j] < shortPath[minWeightNode]) {   
                                minWeightNode = j;   
                            }   
                        }   
                    }   
                    break;   
                }   
            }   
            if (!weightFound[minWeightNode]) {   
                weightFound[minWeightNode] = true;   
                queue.addQueue(minWeightNode);   
            }   
        }   
        return shortPath;   
    }   
       
    /**  
     * 普里姆最小生成树  
     *   
     * @param v  
     */  
    public void primMST(int v) {   
        boolean[] visited = new boolean[length];   
        for (int i = 0; i < length; i++) {   
            visited[i] = false;   
            for (int j = 0; j < length; j++) {   
                lightSide[i][j] = 9999;   
            }   
        }   
        visited[v] = true;   
        Queue queue = new Queue();   
        queue.addQueue(v);   
        while (!queue.isEmpty()) {   
            int temp = queue.front();   
            queue.deleteQueue();   
            int[] ajd = new int[length];   
            int ajdlength = list[temp].getAjd(ajd);   
            for (int i = 0; i < ajdlength; i++) {   
                int w = ajd[i];   
                lightSide[temp][w] = weight[temp][w];   
            }   
            // 找到最小边   
            int minSide = 0;   
            int vfrom =0;   
            int vto = 0;   
            for (int i = 0; i < length; i++) {   
                for (int j = 0; j < length; j++) {   
                    if (visited[i] && visited[j]) {   
                        continue;   
                    }   
                    minSide = lightSide[i][j];   
                    vfrom = i;   
                    vto = j;   
                    for (int k = 0; k < length; k++) {   
                        for (int l = 0; l < length; l++) {   
                            if (visited[k] && visited[l]) {   
                                continue;   
                            }   
                            if (lightSide[k][l] < minSide) {   
                                minSide = lightSide[k][l];   
                                vfrom = k;   
                                vto = l;   
                            }   
                        }   
                    }   
                    break;   
                }   
            }   
            //将最小边的节点vto设为true,并输出vto   
            if (!visited[vto]) {   
                visited[vto] = true;   
                System.out.print(vfrom+"==>" + vto+", ");   
                queue.addQueue(vto);   
            }   
        }   
    }   
       
    /**  
     * 克鲁斯卡尔最小生成树  
     */  
    public void kruskalMST() {   
        int m = 0;   
        while (m < length - 1) {   
            // 找到最小边   
            int minSide = 0;   
            int vfrom = 0;   
            int vto = 0;   
            for (int i = 0; i < length; i++) {   
                for (int j = 0; j < length; j++) {   
                    if (replaceValue[i] == replaceValue[j]) {   
                        continue;   
                    }   
                    minSide = weight[i][j];   
                    vfrom = i;   
                    vto = j;   
                    for (int k = 0; k < length; k++) {   
                        for (int l = 0; l < length; l++) {   
                            if (replaceValue[k] == replaceValue[l]) {   
                                continue;   
                            }   
                            if (weight[k][l] < minSide) {   
                                minSide = weight[k][l];   
                                vfrom = k;   
                                vto = l;   
                            }   
                        }   
                    }   
                    break;   
                }   
            }   
            if (replaceValue[vfrom] != replaceValue[vto]) {   
                System.out.print(vfrom + "==>" + vto + ", ");   
                for (int i = 0; i < length; i++) {   
                    if (replaceValue[i] == replaceValue[vfrom]) {   
                        replaceValue[i] = replaceValue[vto];   
                    }   
                }   
                m++;   
            }   
        }   
    }   
  
    /**    
     * @param args    
     */  
    public static void main(String[] args) {   
        Graph graph = new Graph(6);   
        System.out.println("create graph start");   
        for (int i = 0; i < 6; i++) {   
            graph.addGraph(i);   
        }   
        graph.addDoubleSide(0, 1, 1);   
        graph.addDoubleSide(0, 2, 8);   
        graph.addDoubleSide(0, 3, 7);   
        graph.addDoubleSide(1, 2, 5);   
        graph.addDoubleSide(1, 4, 5);   
        graph.addDoubleSide(1, 5, 4);   
        graph.addDoubleSide(1, 3, 10);   
        graph.addDoubleSide(2, 4, 3);   
        graph.addDoubleSide(4, 5, 6);   
        graph.addDoubleSide(5, 3, 2);   
        graph.print();   
        System.out.println("create graph end");   
        graph.kruskalMST();   
    }   
}  



/**  
 * 佛洛伊德最短路径  
 *   
 * @param v  
 * @return int[]  
 */  
public int[] floydShortPath(int v) {   
    // 初始化矩阵   
    int[][] spath = new int[length][length];   
    for (int i = 0; i < length; i++) {   
        for (int j = 0; j < length; j++) {   
            if (i == j) {   
                spath[i][j] = 0;   
            } else {   
                spath[i][j] = weight[i][j];   
            }   
        }   
    }   
    for (int i = 0; i < length; i++) {   
        for (int j = 0; j < length; j++) {   
            for (int k = 0; k < length; k++) {   
                if (spath[i][j] + spath[k][i] < spath[j][k]) {   
                    spath[j][k] = spath[i][j] + spath[k][i];   
                }   
            }   
        }   
    }   
    int[] resultArray = new int[length];   
    for (int i = 0; i < length; i++) {   
        resultArray[i] = spath[v][i];   
    }   
    return resultArray;   
  
}  

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值