`
leon_a
  • 浏览: 79036 次
  • 性别: Icon_minigender_1
  • 来自: 拜月神教
社区版块
存档分类
最新评论

LCS与图算法

阅读更多
求两个字符串最长公共子串的问题。大体解法是用一个矩阵来记录两个字符串中所有位置的两个字符之间的匹配情况,若是匹配则为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;   
  
}  

分享到:
评论

相关推荐

    LCS动态规划算法实现

    在实际应用中,LCS算法不仅用于字符串的比较,还可以扩展到序列比对,比如在生物信息学中,用于比较DNA或蛋白质序列。此外,它还能应用于文件差异检测、编辑距离计算等场景。 总结来说,"LCS动态规划算法实现"涵盖...

    LCS算法java源代码

    根据LCS算法取出最长公用字符串,实现字符串比较

    最长子序列LCS算法

    最长子序列LCS算法,用于处理最长公共字串问题。 两个序列的LCS问题包含两个序列的前缀的LCS,因此,LCS问题具有最优子结构性质。在设计递归算法时,不难看出递归算法具有子问题重叠的性质。   设C[i,j]C[i,j]...

    LCS最长公共子序列算法

    **最长公共子序列(Longest Common Subsequence, LCS)算法详解** 在计算机科学中,LCS算法是一个经典的字符串处理问题,用于寻找两个序列的最长子序列,这个子...掌握LCS算法有助于理解和解决与序列处理相关的问题。

    lcs.rar_LCS_LCS算法_Lcs.rar_最长公共子序列

    LCS算法旨在找到两个给定序列之间的最长子序列,这个子序列并不需要在原序列中连续出现,但必须保持原有的顺序。 LCS算法的基本思想是采用动态规划来解决。动态规划是一种将复杂问题分解为更小的子问题,并存储这些...

    C#写的LCS算法

    LCS算法的核心在于找到两个序列在不考虑顺序的情况下,最长的共享子序列。这个子序列并不一定是连续的,但它是两个原始序列中的一个子集。例如,序列"ABCBDAB"和"BDCAB"的LCS是"BCAB"。 C#实现LCS算法通常会采用...

    最长公共子序列(LCS)的算法C++实现-已用模板类封装

    LCS算法的精髓就是动态规划,序列其实不仅限于字符序列,因此我用模版类对该算法进行了封装,里面提供了尽量方便的函数来进行该算法的使用,该实现并不追求速度最快化,而是尽量让该算法类能支持重用,若发现算法有...

    LCS(最长公共子序列)算法的实现

    关于LCS(最长公共子序列)算法的实现~ 自己测试通过的

    LCS最长公共字串算法

    最长公共字串算法,为算法导论上的算法,可以运行,运行时间为O(mn)

    LCS.zip_LCS算法

    下面我们将深入探讨LCS算法的原理、实现方式以及它的应用。 ### 1. LCS算法定义 给定两个字符串S1和S2,LCS是指存在于S1和S2中的一个子序列,该子序列不是S1或S2的子串,但与两者都相同,且长度最长。例如,对于...

    算法导论LCS

    LCS算法是一种经典的动态规划问题,其目标是在两个或多个序列中找到最长的相同子序列。这里说的“子序列”是指通过删除原序列中的某些元素(但保持元素顺序不变)得到的序列。LCS问题广泛应用于文本比较、生物信息学...

    LCS算法(连续)

    在本项目中,LCS算法被实现为连续问题的解决方案,使用了C++编程语言,旨在提供稳定且高效的性能。** LCS算法的基本思想是通过动态规划来解决。假设我们有两个字符串X和Y,我们要找它们的最长公共子序列。首先,...

    LCS算法源码

    压缩包中的"LCS算法"可能包含了不同编程语言的实现,如C、Java、Python等,也可能包括了算法的优化版本或者与LCS相关的其他算法,如曼哈顿距离、Levenshtein距离等。通过研究这些源码,我们可以更深入地理解LCS算法...

    带有 LCS算法的图像差异工具_rust_代码_下载

    将 LCS 算法与 Rust 结合,意味着我们可以期待一个快速且低资源消耗的图像差异解决方案。 在【压缩包子文件的文件名称列表】中,我们看到 "lcs-image-diff-rsster" 这个文件名,推测这可能是该项目的主程序或者源...

    字符串相似性算法【最长公共字符串算法】 【LCS】

    `arithmetic.py`可能是包含这种LCS算法实现的文件,或者是与字符串操作或计算相关的其他算法。通过查看这个文件的源代码,可以更深入地理解博主的具体实现方法和可能的优化。 总结来说,LCS算法是一种计算字符串...

    实验九lcs算法.doc

    本实验报告主要围绕LCS算法进行深入理解和实现,通过分析和设计,旨在让学生掌握动态规划的核心思想。 LCS问题的基本定义是:给定两个序列X和Y,找出它们的最长公共子序列,这个子序列不必连续,但要求字符顺序与原...

    带有 LCS 算法的 图像差异工具_rust_代码_下载

    lcs 图像差异 带有 LCS 算法的图像差异库和工具

    lcs算法详解.pdf

    "LCS算法详解.pdf" LCS(Longest Common Subsequence)问题是计算机科学中一个经典的问题,它是指在两个或多个序列中找到最长的公共子序列。这个问题的解决思路有穷举搜索法和动态规划算法两种。 穷举搜索法是最...

    C# LCS 文本比较器

    本文将详细介绍LCS算法及其在C#中的实现,以及如何通过该项目进行文本比较。 LCS算法是一种经典的计算机科学问题,其目标是在两个序列中找到最长的子序列,该子序列同时存在于两个序列中,但并不要求连续。在文本...

    最长公共子序列(LCS)算法源代码和实验报告

    LCS算法的核心在于动态规划。我们可以使用二维数组L[i][j]来存储两个序列X和Y前i个字符与前j个字符的最长公共子序列的长度。基本的递推关系如下: 1. 如果X[i-1] = Y[j-1],则L[i][j] = L[i-1][j-1] + 1,表示在...

Global site tag (gtag.js) - Google Analytics