本打算周末完成这次作业,但没想到遇到了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的更多相关文章

  1. Coursera 算法二 week2 Seam Carving

    这周作业设计到的算法是有向无环图的最短路径算法,只需要按照顶点的拓扑顺序去放松顶点即可.而在这个题目中拓扑顺序就是按照行的顺序或列的顺序. 用到的数据结构为一个二维数组picture同来存储每个像素的 ...

  2. Coursera 算法二 week 3 Baseball Elimination

    这周的作业不需要自己写算法,只需要调用库函数就行,但是有些难以理解,因此用了不少时间. import edu.princeton.cs.algs4.FlowEdge; import edu.princ ...

  3. Coursera 算法二 week 4 Boggle

    这次的作业主要用到了单词查找树和深度优先搜索. 1.在深度优先搜索中,在当前层的递归调用前,将marked数组标记为true.当递归调用返回到当前层时,应将marked数组标记为false.这样既可以 ...

  4. coursera 算法二 week 1 wordnet

    这周的作业可谓是一波三折,但是收获了不少,熟悉了广度优先搜索还有符号图的建立.此外还知道了Integer.MAX_VALUE. SAP: 求v和w的大概思路是对v和w分别广度优先搜索,然后遍历图中每一 ...

  5. TensorFlow 入门之手写识别(MNIST) softmax算法 二

    TensorFlow 入门之手写识别(MNIST) softmax算法 二 MNIST Fly softmax回归 softmax回归算法 TensorFlow实现softmax softmax回归算 ...

  6. 分布式共识算法 (二) Paxos算法

    系列目录 分布式共识算法 (一) 背景 分布式共识算法 (二) Paxos算法 分布式共识算法 (三) Raft算法 分布式共识算法 (四) BTF算法 一.背景 1.1 命名 Paxos,最早是Le ...

  7. Floyd算法(二)之 C++详解

    本章是弗洛伊德算法的C++实现. 目录 1. 弗洛伊德算法介绍 2. 弗洛伊德算法图解 3. 弗洛伊德算法的代码说明 4. 弗洛伊德算法的源码 转载请注明出处:http://www.cnblogs.c ...

  8. Dijkstra算法(二)之 C++详解

    本章是迪杰斯特拉算法的C++实现. 目录 1. 迪杰斯特拉算法介绍 2. 迪杰斯特拉算法图解 3. 迪杰斯特拉算法的代码说明 4. 迪杰斯特拉算法的源码 转载请注明出处:http://www.cnbl ...

  9. Prim算法(二)之 C++详解

    本章是普里姆算法的C++实现. 目录 1. 普里姆算法介绍 2. 普里姆算法图解 3. 普里姆算法的代码说明 4. 普里姆算法的源码 转载请注明出处:http://www.cnblogs.com/sk ...

随机推荐

  1. LightOJ 1214 Large Division

    Large Division Given two integers, a and b, you should check whether a is divisible by b or not. We ...

  2. WCF中的AddressHeader作用

    客户端发送请求给服务端,服务端根据请求消息把消息转发给对应的终结点.这里面有个消息筛选机制,如果请求消息中带有地址报头相关信息,则会用地址报头匹配当前的所有终结点.所以默认情况下客户端和服务端的地址报 ...

  3. Redis---1、介绍

    Redis简介: 是以key-value形式存储,和传统的关系型数据库不一样,不一定遵循传统数据库的一些基本要求. 优点: 对数据高并发读写 对海量数据的高效率存储和访问 对数据的可扩展性和高可用行 ...

  4. OC与JS交互之WKWebView

    上一篇文章我们使用了JavaScriptCore框架重写了之前的示例,iOS8苹果偏爱HTML5,重构了UIWebVIew,给我们带来了WKWebView,使其性能.稳定性.功能大幅度提升,也更好的支 ...

  5. 配置/etc/profile错误导致很多系统命令无法使用

    在配置hadoop的环境变量的过程中,由于字符输入错误导致/etc/profile文件出错,并导致系统的基本命令不能使用,如:vi,ls等. 这种情况,首先修改/etc/profile的错误文件内容, ...

  6. ETL第二篇 调用webservice

    ETL第一篇(Kettle Spoon) 初遇 ETL第二篇 调用webservice 前言 这里使用ETL [Java代码] 实现 代码中使用axis调用webservice 在ETL提供了 Pro ...

  7. 微服务系列(二):使用 API 网关构建微服务

    编者的话|本文来自 Nginx 官方博客,是微服务系列文章的第二篇,本文将探讨:微服务架构是如何影响客户端到服务端的通信,并提出一种使用 API 网关的方法. 作者介绍:Chris Richardso ...

  8. Java代码生成图片验证码

    1.jsp页面显示验证码,src跳转到Controller里的:getImg_validate,reloadImg()作用是点击验证码就会换一张(重新请求getImg_validate) <ul ...

  9. Eclipse设置虚拟机参数 (转 构建内存溢出)

    Java -verbose:gc 中参数-verbose:gc 表示输出虚拟机中GC的详细情况. 首先在Eclipse的Debug页签中设置虚拟机参数: 步骤: 1.选中已经写好的项目 2.Run-& ...

  10. codechef Many Lists(树状数组 set)

    题意 题目链接 Sol 直接做肯定不好搞(反正我不会..) 直接开\(n\)个Pair类型的set,维护每个数的出现位置 每次在set中二分后暴力合并即可 然后就是树状数组的基本操作了 时间复杂度:\ ...