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