Coursera 算法二 week 5 BurrowsWheeler
本打算周末完成这次作业,但没想到遇到了hard deadline,刚开始看不懂题意,后来发现算法4书上有个类似的问题,才理解了题意。最后晚上加班,上课加班,还好在11:35也就是课程结束前25分钟完成了这次作业。。。
本次作业学到的知识点:
1、java中两个类对象比较相等用equals,因此String对象也应用equals方法,而非“==”。
2、读取命令行参数用args[i],读取文件中的数据才用StdIn等。
3、String对象的长度用方法length,数组的长度用length()。
4、类似于int在泛型中用Integer类,char在泛型中应用Charactor类。
5、用Arrays.sort方法对数组进行自定义排序,首先数组应为基本类型对应的类,然后要重载compare方法,这里参考别人的代码使用了匿名内部类,详见CircularSuffixArray类中构造函数。而对基本类型的数组排序,函数参数为数组名即可(见BurrowsWheeler类44行)。
作业中难以理解的一些地方:
1、后缀数组排序是指将每一行中的后缀字符数组看做字符串进行排序。
2、不需要讲后缀数组存储起来,因为如果字符数组在第n行,那么数组就以输入字符串中的第n个字符开始,从而根据输入字符串就可确定此字符数组。
3、BurrowsWheeler类的逆变换中,通过t数组构造一个<字符,字符在t数组中的下标的队列>的符号表,就可以方便的求出next数组。
import java.util.List;
import java.util.ArrayList;
import edu.princeton.cs.algs4.BinaryStdIn;
import edu.princeton.cs.algs4.BinaryStdOut; public class MoveToFront {
// apply move-to-front encoding, reading from standard input and writing to standard output
public static void encode()
{
List<Character> list = new ArrayList<Character>();
for (int i = 0; i < 256; i++)
list.add((char)i);
while (!BinaryStdIn.isEmpty())
{
char c = BinaryStdIn.readChar();
int index = list.indexOf(c);
BinaryStdOut.write(index, 8);
list.remove(index);
list.add(0, c);
}
BinaryStdOut.close();
} // apply move-to-front decoding, reading from standard input and writing to standard output
public static void decode()
{
List<Character> list = new ArrayList<Character>();
for (int i = 0; i < 256; i++)
list.add((char)i);
while (!BinaryStdIn.isEmpty())
{
int index = BinaryStdIn.readChar();
char c = list.get(index);
BinaryStdOut.write(c);
list.remove(index);
list.add(0, c);
}
BinaryStdOut.close();
} // if args[0] is '-', apply move-to-front encoding
// if args[0] is '+', apply move-to-front decoding
public static void main(String[] args)
{
if (args[0].equals("-")) encode();
if (args[0].equals("+")) decode();
}
}
import java.util.Arrays;
import java.util.Comparator; public class CircularSuffixArray {
private String input;
private Integer index[];
// circular suffix array of s
public CircularSuffixArray(String s)
{
if (s == null) throw new java.lang.IllegalArgumentException();
input = s;
index = new Integer[s.length()];
for (int i = 0; i < s.length(); i++)
index[i] = i;
Arrays.sort(index, new Comparator<Integer>() {
public int compare(Integer first, Integer second)
{
int p = first, q = second;
for (int i = 0; i < input.length(); i++)
{
if (p >= input.length()) p = 0;
if (q >= input.length()) q = 0;
if (input.charAt(p) > input.charAt(q)) return 1;
if (input.charAt(p) < input.charAt(q)) return -1;
p++;
q++;
}
return 0;
}
});
}
// length of s
public int length()
{
return index.length;
}
// returns index of ith sorted suffix
public int index(int i)
{
if (i < 0 || i > input.length() - 1)
throw new java.lang.IllegalArgumentException();
return index[i];
}
// unit testing (required)
public static void main(String[] args)
{
CircularSuffixArray csa = new CircularSuffixArray("ABRACADABRA!");
for (int i = 0; i < csa.length(); i++)
System.out.println(csa.index(i));
}
}
import edu.princeton.cs.algs4.BinaryStdIn;
import edu.princeton.cs.algs4.BinaryStdOut;
import java.util.Arrays;
import edu.princeton.cs.algs4.Queue;
import edu.princeton.cs.algs4.ST; public class BurrowsWheeler {
// apply Burrows-Wheeler transform, reading from standard input and writing to standard output
public static void transform()
{
String input = BinaryStdIn.readString();
CircularSuffixArray csa = new CircularSuffixArray(input);
for (int i = 0; i < csa.length(); i++)
if (csa.index(i) == 0)
BinaryStdOut.write(i);
for (int i = 0; i < csa.length(); i++)
{
int index = csa.index(i) - 1;
if (index < 0) index = csa.length() - 1;
char c = input.charAt(index);
BinaryStdOut.write(c);
}
BinaryStdOut.close();
} // apply Burrows-Wheeler inverse transform, reading from standard input and writing to standard output
public static void inverseTransform()
{
int first = BinaryStdIn.readInt();
String chars = BinaryStdIn.readString();
char[] t = chars.toCharArray();
chars = null;
int i = 0, size = t.length;
ST<Character, Queue<Integer>> st = new ST<Character, Queue<Integer>>();
for (i = 0; i < size; i++)
{
if (st.contains(t[i])) st.get(t[i]).enqueue(i);
else {
Queue<Integer> q = new Queue<Integer>();
q.enqueue(i);
st.put(t[i], q);
}
}
Arrays.sort(t);
int next[] = new int[size];
for (i = 0; i < size; i++)
next[i] = st.get(t[i]).dequeue();
for (i = 0; i < size; i++)
{
BinaryStdOut.write(t[first]);
first = next[first];
}
BinaryStdOut.close();
} // if args[0] is '-', apply Burrows-Wheeler transform
// if args[0] is '+', apply Burrows-Wheeler inverse transform
public static void main(String[] args)
{
if (args[0].equals("-")) transform();
if (args[0].equals("+")) inverseTransform();
}
}
Coursera 算法二 week 5 BurrowsWheeler的更多相关文章
- Coursera 算法二 week2 Seam Carving
这周作业设计到的算法是有向无环图的最短路径算法,只需要按照顶点的拓扑顺序去放松顶点即可.而在这个题目中拓扑顺序就是按照行的顺序或列的顺序. 用到的数据结构为一个二维数组picture同来存储每个像素的 ...
- Coursera 算法二 week 3 Baseball Elimination
这周的作业不需要自己写算法,只需要调用库函数就行,但是有些难以理解,因此用了不少时间. import edu.princeton.cs.algs4.FlowEdge; import edu.princ ...
- Coursera 算法二 week 4 Boggle
这次的作业主要用到了单词查找树和深度优先搜索. 1.在深度优先搜索中,在当前层的递归调用前,将marked数组标记为true.当递归调用返回到当前层时,应将marked数组标记为false.这样既可以 ...
- coursera 算法二 week 1 wordnet
这周的作业可谓是一波三折,但是收获了不少,熟悉了广度优先搜索还有符号图的建立.此外还知道了Integer.MAX_VALUE. SAP: 求v和w的大概思路是对v和w分别广度优先搜索,然后遍历图中每一 ...
- TensorFlow 入门之手写识别(MNIST) softmax算法 二
TensorFlow 入门之手写识别(MNIST) softmax算法 二 MNIST Fly softmax回归 softmax回归算法 TensorFlow实现softmax softmax回归算 ...
- 分布式共识算法 (二) Paxos算法
系列目录 分布式共识算法 (一) 背景 分布式共识算法 (二) Paxos算法 分布式共识算法 (三) Raft算法 分布式共识算法 (四) BTF算法 一.背景 1.1 命名 Paxos,最早是Le ...
- Floyd算法(二)之 C++详解
本章是弗洛伊德算法的C++实现. 目录 1. 弗洛伊德算法介绍 2. 弗洛伊德算法图解 3. 弗洛伊德算法的代码说明 4. 弗洛伊德算法的源码 转载请注明出处:http://www.cnblogs.c ...
- Dijkstra算法(二)之 C++详解
本章是迪杰斯特拉算法的C++实现. 目录 1. 迪杰斯特拉算法介绍 2. 迪杰斯特拉算法图解 3. 迪杰斯特拉算法的代码说明 4. 迪杰斯特拉算法的源码 转载请注明出处:http://www.cnbl ...
- Prim算法(二)之 C++详解
本章是普里姆算法的C++实现. 目录 1. 普里姆算法介绍 2. 普里姆算法图解 3. 普里姆算法的代码说明 4. 普里姆算法的源码 转载请注明出处:http://www.cnblogs.com/sk ...
随机推荐
- 用canvas和原生js写的一个笨鸟先飞的小游戏(暂时只有一个关卡)
其中一个画布背景是一张图片,还有小鸟,两个管子的图片.暂时不知道怎么附上去就不添加了.这里只有源代码,css和js都是在html写着的,感觉比他们的容易吧,hah <!DOCTYPE html& ...
- 问题集录--Android:解决Studio新建项目时,在 Building gradle project info 一直卡住
Android Studio导入项目的时候,一直卡在Building gradle project info这一步,主要原因还是因为被墙的结果.gradle官网虽然可以访问,但是速度连蜗牛都赶不上.. ...
- php 数组任意位置插入值
array_splice() $arr = array('A', 'B', 'C'); $arr2 = 'abc';$t = array_splice($arr, 1, 0, $arr2); prin ...
- C++ 语法积累20161015
1.break 作用:用于终止当前循环(跳出循环体). 遇到最多的应该是在双层循环体中的使用: (1)在内循环体中,遇到break,则直接跳出内循环体,再次执行外循环体. (2) 在外循环体中,bre ...
- UML 简介笔记
1. UML 是什么? UML 统一建模语言是一组图形表示法,可以帮助描述和设计软件系统,特别是使用面向对象 OO 风格建造的软件系统. 2. 使用 UML 的方式 UML 有 3 种使用模式:草稿, ...
- JS获取今天年月日
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Mac(OS X)中Git安装与GitHub基本使用
GitHub是一个面向开源及私有软件项目的托管平台.开源代码库以及版本控制系统,因为只支持 Git 作为唯一的版本库格式进行托管,故名 GitHub.通常在Windows下使用GitHub的教程是非常 ...
- DOM基础代码练习(一)
上一篇介绍了一下DOM的一些基础的知识,这里我整理了一些有关上一篇知识点的一些封装函数. 1.遍历元素节点 function retChild(node) { var child = node.chi ...
- javascript实现深克隆的几种方法
1)普通函数实现 function cloneObject(obj) { if (obj === null || typeof obj !== 'object') { return obj; } va ...
- Luogu4887 第十四分块(前体)
sto \(lxl\) orz 考虑莫队,每次移动端点,我们都要询问区间内和当前数字异或有 \(k\) 个 \(1\) 的数字个数 询问 \([l,r]\) 可以再次离线,拆成询问 \([1,l-1] ...