您的位置:首页 > 编程语言 > Java开发

Coursera普林斯顿算法课第二次作业

2018-03-25 12:53 1186 查看
Deque: 使用LinkedList和哨兵节点即可。import java.util.Iterator;
import java.util.NoSuchElementException;

import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.Stopwatch;

public class Deque<Item> implements Iterable<Item> {

private int num; // number of nodes
private Node first;
private Node last;

public Deque(){
this.num = 0;
this.first = null;
this.last = null;
}

private class Node{
private Item item;
private Node next;
private Node prev;
}

public boolean isEmpty(){
return first == null;
}

public int size(){
return num;
}

// add the item to the front
public void addFirst(Item item){
if(item == null) throw new IllegalArgumentException();

Node oldfirst = first;
first = new Node();
first.item = item;
first.prev = null;

if(oldfirst == null){
last = first;
first.next = null;
}else{
first.next = oldfirst;
oldfirst.prev = first;

}
num++;
}

// add the item to the end
public void addLast(Item item){
if(item == null) throw new IllegalArgumentException();

Node oldlast = last;
last = new Node();
last.item = item;
last.next = null;

if(isEmpty()){
first = last;
last.prev = null;
}else{
oldlast.next = last;
last.prev = oldlast;
}
num++;
}

// remove and return the item from the front
public Item removeFirst(){
if(isEmpty()) throw new NoSuchElementException();

Item it = first.item;
first = first.next;
num--;

if(num == 0) last = null;
else first.prev = null;

return it;

}

public Item removeLast(){
if(isEmpty()) throw new NoSuchElementException();

Item it = last.item;
last = last.prev;
num--;

if(num == 0) first = null;
else last.next = null;

return it;
}

// return an iterator over items in order from front to end
public Iterator<Item> iterator(){
return new DequeIterator();
}

private class DequeIterator implements Iterator<Item>{

private Node current = first;

public boolean hasNext() {return current != null;}
public void remove() {throw new UnsupportedOperationException();}

public Item next() {

if(!hasNext()) throw new NoSuchElementException();

Item it = current.item;
current = current.next;
return it;
}
}

// test
public static void main(String[] args){
Deque<String> dq = new Deque<String>();
dq.addFirst("I");
dq.addFirst("am");
dq.addFirst("Hugh");
dq.addLast("I");
dq.addLast("Love");
dq.addLast("Gals");

Stopwatch sw = new Stopwatch();

for(String s:dq){ StdOut.println(s);}
StdOut.println("remove first: "+dq.removeFirst());
StdOut.println("remove last: "+dq.removeLast());
for(String s:dq){ StdOut.println(s);}

StdOut.println("elapsed CPU time: "+sw.elapsedTime());
}

}
RandomizedQueue: 使用ResizedArray实现,关键在于在每次dequeue操作后需要把末端节点存储的item转存到被随机移除item的节点处,然后将尾端节点设为null,避免loitering。同时也能避免wrap-around的问题,即不会出现数组前几项被dequeue后值为null的情况。import java.util.Iterator;
import java.util.NoSuchElementException;

import edu.princeton.cs.algs4.StdRandom;

public class RandomizedQueue<Item> implements Iterable<Item> {

private Item[] que;
private int num; // number of elements on queue

public RandomizedQueue(){
que = (Item[]) new Object[2];
num = 0;
}

public boolean isEmpty(){
return num == 0;
}

public int size(){
return num;
}

private void resize(int capacity){
assert capacity >= num;
Item[] temp = (Item[]) new Object[capacity];

for(int i=0; i<num; i++){
temp[i] = que[i];
}

que = temp;
}

public void enqueue(Item item){
if(item == null) throw new IllegalArgumentException();
if(num == que.length) resize(2 * que.length);

que[num++] = item;
}

// remove and return a random item
public Item dequeue(){
if(isEmpty()) throw new NoSuchElementException();

int ch = StdRandom.uniform(num);
Item it = que[ch];

if(ch != num-1) que[ch] = que[num-1];
que[num-1] = null; // to avoid loitering
num--;

if(num > 0 && num == que.length / 4) resize(que.length / 2);
return it;
}

// return a random item but not remove it
public Item sample(){
if(isEmpty()) throw new NoSuchElementException();

int ch = StdRandom.uniform(num);
return que[ch];
}

// return an independent iterator over items in random order
public Iterator<Item> iterator() {
return new RandomizedQueueIterator();
}

private class RandomizedQueueIterator implements Iterator<Item>{

private Item[] rdq; // independent iterator
private int current;

public RandomizedQueueIterator(){

rdq = (Item[]) new Object[num];
current = 0;

for(int k=0; k<num; k++){
rdq[k] = que[k];
}

StdRandom.shuffle(rdq);
}

public boolean hasNext() {return current < num;}
public void remove() {throw new UnsupportedOperationException();}

public Item next() {

if(!hasNext()) throw new NoSuchElementException();

Item it = rdq[current];
current++;
return it;
}
}

}

Permutation:注意k是从命令行获取的,以及不要有多余的输出。在参考资料中提到了新建字符串数组和使用readStrings函数获得bonus的方法,不过实际测试时却发现如下错误:
[ERROR] Permutation.java:11: Do not declare arrays in this program. [Performance]

[ERROR] Permutation.java:11:44: Do not call 'StdIn.readAllStrings()' in this program. Use only 'StdIn.readString()'. 
import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;

public class Permutation {

public static void main(String[] args){

RandomizedQueue<String> r = new RandomizedQueue<String>();
//StdOut.println(" size: " + r.size());

// input from command line
int k = Integer.parseInt(args[0]);

String s;
//StdOut.println("Input strings: "); -> no redundant output!

// use ctrl+z to end input
while(!StdIn.isEmpty()){
//r.enqueue(s); -> the last string won't be enqueued!
s = StdIn.readString();
r.enqueue(s);
}

int count = 0;
for(String ss:r){
if(count < k){
StdOut.println(ss);
count++;
}else break;
}

}

}

references: https://blog.csdn.net/sesiria/article/details/52586467 https://segmentfault.com/a/1190000005345079 https://blog.csdn.net/tumaolin94/article/details/43448485
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java algorithm