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

    原创地址:https://blog.csdn.net/u012166958/article/details/64920144 标准的Modbus 口是使用RS-232C 兼容串行接口,它定义了连接口的 ...

  2. 目前还活着的erlang web框架的比较

    参见 https://github.com/ChicagoBoss/ChicagoBoss/wiki/Comparison-of-Erlang-Web-Frameworks

  3. 从错误0x80070522,谈强制完整性控制(MIC)。

    在Windows 7碰到一个奇怪的问题,DE二个盘,NTFS的权限(属性--安全页)一模一样,没有任何区别,但在E盘根目录可以创建文件或文件夹,而在D盘根目录下报错:0x80070522,如果使用应用 ...

  4. vue img标签图片加载时 闪烁

    //jsdata(){ return{ img_url: '', } },created(){ //请求数据,并给图片赋值url ajax.get(http_url) .then(res=>{ ...

  5. Selenium Python FirefoxWebDriver处理打开保存对话框

    代码如下(网上示例): #profile =  webdriver.FirefoxProfile(r"C:\Users\Skyyj\AppData\Roaming\Mozilla\Firef ...

  6. 【java】之类加载机制

    类加载: 类加载机制是指.class文件加载到jvm,并形成Class对象的机制,之后的应用就可对Class对象进行实例化并调用,类加载机制可在运行时动态加载外部的类,远程网络下载过来的class文件 ...

  7. C/C++基础----用于大型程序的工具(异常处理,命名空间,多重继承)

    独立开发的子系统间协同处理错误的能力 使用各种库(可能包含独立开发的库进行协同开发的能力) 对比复杂的应用概念建模的能力 异常处理 异常将问题的检测和解决过程分离开 当执行一个throw之后,程序控制 ...

  8. python3实现mysql导出excel

    Mysql中'employee'表内容如下: # __Desc__ = 从数据库中导出数据到excel数据表中 import xlwt import pymysql class MYSQL: def ...

  9. python-selenium并发执行测试用例(方法一 各模块每一条并发执行)

    总执行代码: # coding=utf-8import unittest,os,timeimport HTMLTestRunnerimport threadingimport syssys.path. ...

  10. 如何获取阿里云OSS上每个文件夹的大小

    原文 https://help.aliyun.com/document_detail/88458.html?spm=a2c4g.11186623.2.11.792462b15oU02q OSS文件按照 ...