▶ 书中第六章部分程序,包括在加上自己补充的代码,利用后缀树查找最长重复子串、查找最大重复子串并输出其上下文(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的更多相关文章

  1. 《算法》第六章部分程序 part 7

    ▶ 书中第六章部分程序,加上自己补充的代码,包括全局最小切分 Stoer-Wagner 算法,最小权值二分图匹配 ● 全局最小切分 Stoer-Wagner 算法 package package01; ...

  2. 《算法》第六章部分程序 part 6

    ▶ 书中第六章部分程序,包括在加上自己补充的代码,包括二分图最大匹配(最小顶点覆盖)的交替路径算法和 HopcroftKarp 算法 ● 二分图最大匹配(最小顶点覆盖)的交替路径算法 package ...

  3. 《算法》第六章部分程序 part 5

    ▶ 书中第六章部分程序,包括在加上自己补充的代码,网络最大流 Ford - Fulkerson 算法,以及用到的流量边类和剩余流量网络类 ● 网络最大流 Ford - Fulkerson 算法 pac ...

  4. 《算法》第六章部分程序 part 8

    ▶ 书中第六章部分程序,加上自己补充的代码,包括单纯形法求解线性规划问题 ● 单纯形法求解线性规划问题 // 表上作业法,I 为单位阵,y 为对偶变量,z 为目标函数值 // n m 1 // ┌── ...

  5. 《算法》第六章部分程序 part 3

    ▶ 书中第六章部分程序,包括在加上自己补充的代码,后缀树的两种实现 ● 后缀树实现一 package package01; import java.util.Arrays; import edu.pr ...

  6. 《算法》第六章部分程序 part 2

    ▶ 书中第六章部分程序,包括在加上自己补充的代码,B-树 ● B-树 package package01; import edu.princeton.cs.algs4.StdOut; public c ...

  7. 《算法》第六章部分程序 part 1

    ▶ 书中第六章部分程序,包括在加上自己补充的代码,粒子碰撞系统及用到的粒子类 ● 粒子系统 package package01; import java.awt.Color; import edu.p ...

  8. 《算法》第一章部分程序 part 1

    ▶ 书中第一章部分程序,加上自己补充的代码,包括若干种二分搜索,寻找图上连通分量数的两种算法 ● 代码,二分搜索 package package01; import java.util.Arrays; ...

  9. 《算法》第二章部分程序 part 5

    ▶ 书中第二章部分程序,加上自己补充的代码,包括利用优先队列进行多路归并和堆排序 ● 利用优先队列进行多路归并 package package01; import edu.princeton.cs.a ...

随机推荐

  1. ubuntu--Supervisor进程管理工具

    安装,这个程序使用python写的 sudo apt-get install supervisor 配置一个你需要的配置文件 //进入 /etc/supervisor/conf.d文件目录,配置一个r ...

  2. [Android] JNI中的Local Reference

    参考文章:<在 JNI 编程中避免内存泄漏> 一.Local Reference 深层解析 JNI Local Reference 的生命期是在 native method 的执行期(从 ...

  3. npm yarn安装包

  4. 关于linux中的system函数

    Linux下使用system()函数一定要谨慎 https://blog.csdn.net/senen_wakk/article/details/51496322 system()正确应用 https ...

  5. Android开发之Activity(cho1)篇

    一.Activity判断网络是否连通: 首先创建一个Andorid Project项目,然后添加一个on1类,Layout一个button控件和Textview控件. values有一个Color.x ...

  6. linux一些基本知识

    一.linux i386是32位的,amd64是64位(一般情况不限intel或者amd)       server是服务器版,desktop是桌面版 Desktop是社区开源版,拥有一些新功能新软件 ...

  7. [转][C#]TopSelf

    新建一个批处理,用于启动 TopSelf 服务 @echo off Service.exe install net start Service 或者简化成 @echo off Service.exe ...

  8. Charles问题

    1.内容显示乱码 1.1.使用Charles抓包,text显示乱码,note提示如下 SSL Proxying not enabled for this host: enable in Proxy S ...

  9. HDOJ 2002 计算球体积

    #include<cstdio> #define PI 3.1415927 int main() { double r; while (scanf_s("%lf", & ...

  10. Linux创建桥接网络

    图形化创建 #nm-connection-editor & 选择桥接 设置桥接网络 点击添加 模式选择以太网 添加上行网卡 # brctl show 删除桥接 # nmcli connecti ...