《算法》第六章部分程序 part 4
▶ 书中第六章部分程序,包括在加上自己补充的代码,利用后缀树查找最长重复子串、查找最大重复子串并输出其上下文(Key word in context,KWIC)、求两字符串的最长公共子串
● 利用后缀树查找最长重复子串
package package01; import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.SuffixArrayX; public class class01
{
private class01() {} public static String lrs(String text)
{
int n = text.length();
SuffixArrayX sa = new SuffixArrayX(text);
String lrs = "";
for (int i = 1; i < n; i++) // 遍历一次,记录最长公共前缀
{
int length = sa.lcp(i);
if (length > lrs.length())
lrs = text.substring(sa.index(i), sa.index(i) + length);
}
return lrs;
} public static void main(String[] args)
{
String text = StdIn.readAll().replaceAll("\\s+", " "); // 空白字符全部换成 ' '
StdOut.println("'" + lrs(text) + "'");
}
}
● 利用后缀树查找最大重复子串并输出其上下文(Key word in context,KWIC)
package package01; import edu.princeton.cs.algs4.In;
import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.SuffixArrayX; public class class01
{
private class01() {} public static void main(String[] args)
{
In in = new In(args[0]); // 命令参数,分别为输入文件和需要输出的上下文字符数量
int context = Integer.parseInt(args[1]);
String text = in.readAll().replaceAll("\\s+", " ");
int n = text.length();
SuffixArrayX sa = new SuffixArrayX(text); for (; StdIn.hasNextLine(); StdOut.println())
{
String query = StdIn.readLine();
for (int i = sa.rank(query); i < n; i++)
{
int from1 = sa.index(i), to1 = Math.min(n, from1 + query.length()); // 取 index[i] 的头和尾,要求它和 query 不同
if (!query.equals(text.substring(from1, to1)))
break;
int from2 = Math.max(0, sa.index(i) - context), to2 = Math.min(n, sa.index(i) + context + query.length());
StdOut.println(text.substring(from2, to2)); // 向前向后各取 context 个字符
}
}
}
}
● 利用后缀树求两字符串的最长公共子串
package package01; import edu.princeton.cs.algs4.In;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.SuffixArrayX; public class class01
{
private class01() {} private static String lcp(String s, int p, String t, int q) // 返回 s[p] 和 t[q] 开始的两个子串的最大公共子串
{
int n = Math.min(s.length() - p, t.length() - q);
for (int i = 0; i < n; i++) // 逐元素比较就好了,返回保持相等的最长子串
{
if (s.charAt(p + i) != t.charAt(q + i))
return s.substring(p, p + i);
}
return s.substring(p, p + n);
} private static int compare(String s, int p, String t, int q) // 比较两个后缀元素的字典序,用于判断哪个后缀元素要改用下一个
{
int n = Math.min(s.length() - p, t.length() - q);
for (int i = 0; i < n; i++)
{
if (s.charAt(p + i) != t.charAt(q + i))
return s.charAt(p + i) - t.charAt(q + i);
}
if (s.length() - p < t.length() - q)
return -1;
else if (s.length() - p > t.length() - q)
return +1;
return 0;
} public static String lcs(String s, String t)
{
SuffixArrayX suffix1 = new SuffixArrayX(s), suffix2 = new SuffixArrayX(t);
String lcs = "";
for (int i = 0, j = 0; i < s.length() && j < t.length();) // 两个后缀数组比较 O(s.length() + t.length()) 次
{ // 每次检查两个后缀元素的最长相等子串
int p = suffix1.index(i), q = suffix2.index(j); // 一旦找到不相等的元素,字典序靠前的元素就取下一个后缀元素继续比较
String x = lcp(s, p, t, q);
if (x.length() > lcs.length())
lcs = x;
if (compare(s, p, t, q) < 0)
i++;
else
j++;
}
return lcs;
} public static void main(String[] args)
{
In in1 = new In(args[0]), in2 = new In(args[1]);
String s = in1.readAll().trim().replaceAll("\\s+", " ");
String t = in2.readAll().trim().replaceAll("\\s+", " ");
StdOut.println("'" + lcs(s, t) + "'");
}
}
《算法》第六章部分程序 part 4的更多相关文章
- 《算法》第六章部分程序 part 7
▶ 书中第六章部分程序,加上自己补充的代码,包括全局最小切分 Stoer-Wagner 算法,最小权值二分图匹配 ● 全局最小切分 Stoer-Wagner 算法 package package01; ...
- 《算法》第六章部分程序 part 6
▶ 书中第六章部分程序,包括在加上自己补充的代码,包括二分图最大匹配(最小顶点覆盖)的交替路径算法和 HopcroftKarp 算法 ● 二分图最大匹配(最小顶点覆盖)的交替路径算法 package ...
- 《算法》第六章部分程序 part 5
▶ 书中第六章部分程序,包括在加上自己补充的代码,网络最大流 Ford - Fulkerson 算法,以及用到的流量边类和剩余流量网络类 ● 网络最大流 Ford - Fulkerson 算法 pac ...
- 《算法》第六章部分程序 part 8
▶ 书中第六章部分程序,加上自己补充的代码,包括单纯形法求解线性规划问题 ● 单纯形法求解线性规划问题 // 表上作业法,I 为单位阵,y 为对偶变量,z 为目标函数值 // n m 1 // ┌── ...
- 《算法》第六章部分程序 part 3
▶ 书中第六章部分程序,包括在加上自己补充的代码,后缀树的两种实现 ● 后缀树实现一 package package01; import java.util.Arrays; import edu.pr ...
- 《算法》第六章部分程序 part 2
▶ 书中第六章部分程序,包括在加上自己补充的代码,B-树 ● B-树 package package01; import edu.princeton.cs.algs4.StdOut; public c ...
- 《算法》第六章部分程序 part 1
▶ 书中第六章部分程序,包括在加上自己补充的代码,粒子碰撞系统及用到的粒子类 ● 粒子系统 package package01; import java.awt.Color; import edu.p ...
- 《算法》第一章部分程序 part 1
▶ 书中第一章部分程序,加上自己补充的代码,包括若干种二分搜索,寻找图上连通分量数的两种算法 ● 代码,二分搜索 package package01; import java.util.Arrays; ...
- 《算法》第二章部分程序 part 5
▶ 书中第二章部分程序,加上自己补充的代码,包括利用优先队列进行多路归并和堆排序 ● 利用优先队列进行多路归并 package package01; import edu.princeton.cs.a ...
随机推荐
- GetClass与RegisterClass的应用一例
利用GetClass与RegisterClass可以实现根据字符串来实例化具体的子类,这对于某些需要动态配置程序的场合是很有用的.其他的应用如子窗体切换,算法替换等都能得到应用. unit Examp ...
- Azure SQL 数据库仓库Data Warehouse (3) DWU
<Windows Azure Platform 系列文章目录> 在笔者的上一篇文章中:Azure SQL 数据库仓库Data Warehouse (2) 架构 介绍了SQL DW的工作节点 ...
- java网络编程Socket通信详解
Java最初是作为网络编程语言出现的,其对网络提供了高度的支持,使得客户端和服务器的沟通变成了现实,而在网络编程中,使用最多的就是Socket.像大家熟悉的QQ.MSN都使用了Socket相关的技术. ...
- NIO基本操作
NIO是Java 4里面提供的新的API,目的是用来解决传统IO的问题 NIO主要有三大核心部分:Channel(通道),Buffer(缓冲区), Selector(选择器) Channel(通道) ...
- [蓝桥杯]ALGO-92.算法训练_前缀表达式
问题描述 编写一个程序,以字符串方式输入一个前缀表达式,然后计算它的值.输入格式为:“运算符 对象1 对象2”,其中,运算符为“+”(加法).“-”(减法).“*”(乘法)或“/”(除法),运算对象为 ...
- LeetCode——5.Longest Palindromic Substring
一.题目链接:https://leetcode.com/problems/longest-palindromic-substring/ 二.题目大意: 给定一个字符串,找出它最长的回文子串.例如,字符 ...
- gitlab ssh clone问题解决
公司搭建的gitlab,通过http协议可以clone: [sisi@pre-srv24 gitlab]$ git clone http://gitlab.test.mycompany.com/dev ...
- uoj #49. 【UR #3】铀仓库
http://uoj.ac/problem/49 这题二分答案可以做,同时存在另一个直接二分的解法. 考虑对每个点,二分能向左右延伸的最大半径,由于权值范围较大,不能O(1)查询向一侧走指定距离后到达 ...
- [转].NET Framework、C#、CLR和Visual Studo之间的版本关系
原文地址:http://www.xcode.me/more/microsoft-net-framework-version-define C#版本 .NET Framework版本 CLR版本 Vis ...
- JVM异常之:栈溢出StackOverflowError
在java虚拟机规范中,虚拟机栈和本地方法栈都会出现StackOverflowError和OutofMemoryError,程序计数器是java虚拟机中唯一一块不会产生error的内存区域. 一.St ...