From af0cd725985ecf081e49da340f28e7c087788ac1 Mon Sep 17 00:00:00 2001 From: Adrian Istrate Date: Sun, 25 Dec 2011 22:40:33 +0100 Subject: [PATCH] Section 1.3, end of Linked-List Exercises (Ex. 1.3.31). --- .../DoublyLinkedList.java | 406 +++++++++++ .../1-3-BagsQueuesStacks/Evaluate.java | 62 ++ .../1-3-BagsQueuesStacks/EvaluatePostfix.java | 61 ++ .../1-3-BagsQueuesStacks/Ex_1_3_03.java | 74 ++ .../1-3-BagsQueuesStacks/Ex_1_3_04.java | 42 ++ .../1-3-BagsQueuesStacks/Ex_1_3_09.java | 52 ++ .../1-3-BagsQueuesStacks/Ex_1_3_29.java | 129 ++++ .../FixedCapacityStack.java | 62 ++ .../FixedCapacityStackOfStrings.java | 63 ++ .../1-3-BagsQueuesStacks/InfixToPostfix.java | 52 ++ 1-Fundamentals/1-3-BagsQueuesStacks/List.java | 649 ++++++++++++++++++ .../1-3-BagsQueuesStacks/Parentheses.java | 58 ++ .../1-3-BagsQueuesStacks/Stats.java | 42 ++ 13 files changed, 1752 insertions(+) create mode 100644 1-Fundamentals/1-3-BagsQueuesStacks/DoublyLinkedList.java create mode 100644 1-Fundamentals/1-3-BagsQueuesStacks/Evaluate.java create mode 100644 1-Fundamentals/1-3-BagsQueuesStacks/EvaluatePostfix.java create mode 100644 1-Fundamentals/1-3-BagsQueuesStacks/Ex_1_3_03.java create mode 100644 1-Fundamentals/1-3-BagsQueuesStacks/Ex_1_3_04.java create mode 100644 1-Fundamentals/1-3-BagsQueuesStacks/Ex_1_3_09.java create mode 100644 1-Fundamentals/1-3-BagsQueuesStacks/Ex_1_3_29.java create mode 100644 1-Fundamentals/1-3-BagsQueuesStacks/FixedCapacityStack.java create mode 100644 1-Fundamentals/1-3-BagsQueuesStacks/FixedCapacityStackOfStrings.java create mode 100644 1-Fundamentals/1-3-BagsQueuesStacks/InfixToPostfix.java create mode 100644 1-Fundamentals/1-3-BagsQueuesStacks/List.java create mode 100644 1-Fundamentals/1-3-BagsQueuesStacks/Parentheses.java create mode 100644 1-Fundamentals/1-3-BagsQueuesStacks/Stats.java diff --git a/1-Fundamentals/1-3-BagsQueuesStacks/DoublyLinkedList.java b/1-Fundamentals/1-3-BagsQueuesStacks/DoublyLinkedList.java new file mode 100644 index 0000000..d55988b --- /dev/null +++ b/1-Fundamentals/1-3-BagsQueuesStacks/DoublyLinkedList.java @@ -0,0 +1,406 @@ + +/************************************************************************* + * + * Exercise 1.3.31 + * + *************************************************************************/ + +import java.util.Iterator; +import java.util.NoSuchElementException; + +public class DoublyLinkedList implements Iterable +{ + private int N; + private DoubleNode first; + private DoubleNode last; + + private class DoubleNode + { + private DoublyLinkedList parent = list(); + private Item item; + private DoubleNode prev; + private DoubleNode next; + } + + private DoublyLinkedList list() + { + return this; + } + + public DoublyLinkedList() + { + first = null; + last = null; + } + + public DoublyLinkedList(Item[] a) + { + for (Item t : a) + append(t); + } + + public DoublyLinkedList(Iterable coll) + { + for (Item t : coll) + append(t); + } + + public boolean isEmpty() + { + return first == null; + } + + public int size() + { + return N; + } + + public Item first() + { + if (isEmpty()) throw new RuntimeException("List is empty"); + return first.item; + } + + public Item last() + { + if (isEmpty()) throw new RuntimeException("List is empty"); + return last.item; + } + + public DoubleNode node(int k) + { + DoubleNode curr = null; + int i = 1; + + if (k > 0) + { + curr = first; + while (i < k && curr != null) + { + curr = curr.next; + i++; + } + } + else if (k < 0) + { + k = -k; + curr = last; + while (i < k && curr != null) + { + curr = curr.prev; + i++; + } + } + + return curr; + } + + public void prepend(Item item) + { + DoubleNode x = new DoubleNode(); + x.item = item; + if (isEmpty()) { first = x; last = x; } + else { x.next = first; first.prev = x; first = x; } + N++; + } + + public void append(Item item) + { + DoubleNode x = new DoubleNode(); + x.item = item; + if (isEmpty()) { first = x; last = x; } + else { x.prev = last; last.next = x; last = x; } + N++; + } + + public void insertBefore(DoubleNode node, Item item) + { + if (node.parent != this) throw new RuntimeException("Node does not belong to list."); + + if (node == first) + prepend(item); + else + { + DoubleNode prev = node.prev; + DoubleNode x = new DoubleNode(); + x.item = item; + x.prev = prev; + x.next = node; + prev.next = x; + node.prev = x; + N++; + } + } + + public void insertAfter(DoubleNode node, Item item) + { + if (node.parent != this) throw new RuntimeException("Node does not belong to list."); + + if (node == last) + append(item); + else + { + DoubleNode next = node.next; + DoubleNode x = new DoubleNode(); + x.item = item; + x.prev = node; + x.next = next; + next.prev = x; + node.next = x; + N++; + } + } + + public Item removeFirst() + { + if (isEmpty()) throw new RuntimeException("List is empty"); + Item item = first.item; + first.parent = null; + if (first.next != null) first.next.prev = null; + first = first.next; + N--; + if (first == null) last = null; // to avoid loitering + return item; + } + + public Item removeLast() + { + if (isEmpty()) throw new RuntimeException("List is empty"); + Item item = last.item; + last.parent = null; + if (last.prev != null) last.prev.next = null; + last = last.prev; + N--; + if (last == null) first = null; // to avoid loitering + return item; + } + + public Item remove(DoubleNode node) + { + if (node.parent != this) throw new RuntimeException("Node does not belong to list."); + + if (node == first) + return removeFirst(); + else if (node == last) + return removeLast(); + else + { + node.parent = null; + DoubleNode prev = node.prev, + next = node.next; + prev.next = node.next; + next.prev = node.prev; + N--; + return node.item; + } + } + + public String toString() + { + StringBuilder s = new StringBuilder(); + for (Item item : this) + s.append(item + " "); + return s.toString(); + } + + public Iterator iterator() + { + return new ListIterator(); + } + + private class ListIterator implements Iterator + { + private DoubleNode current = first; + + public boolean hasNext() { return current != null; } + public void remove() { throw new UnsupportedOperationException(); } + + public Item next() + { + if (!hasNext()) throw new NoSuchElementException(); + Item item = current.item; + current = current.next; + return item; + } + } + + /** + * Used in unit tests, to verify that the list is double-linked correctly. + */ + public Iterable reversed() + { + return new ReverseIterable(); + } + + private class ReverseIterable implements Iterable + { + public String toString() + { + StringBuilder s = new StringBuilder(); + for (Item item : this) + s.append(item + " "); + return s.toString(); + } + + public Iterator iterator() + { + return new ReverseListIterator(); + } + + private class ReverseListIterator implements Iterator + { + private DoubleNode current = last; + + public boolean hasNext() { return current != null; } + public void remove() { throw new UnsupportedOperationException(); } + + public Item next() + { + if (!hasNext()) throw new NoSuchElementException(); + Item item = current.item; + current = current.prev; + return item; + } + } + } + + + /************ + * Unit tests + ************/ + + private static void testPrepend() + { + StdOut.println("prepend:"); + + int[] a = { 2, 4, 6, 8, 10 }; + DoublyLinkedList lst = new DoublyLinkedList(); + + for (int i = 0; i < a.length; i++) + lst.prepend(a[i]); + showList(lst); + StdOut.println(); + } + + private static void testAppend() + { + StdOut.println("append:"); + + int[] a = { 2, 4, 6, 8, 10 }; + DoublyLinkedList lst = new DoublyLinkedList(); + + for (int i = 0; i < a.length; i++) + lst.append(a[i]); + showList(lst); + StdOut.println(); + } + + private static void testRemoveFirst() + { + StdOut.println("removeFirst:"); + DoublyLinkedList lst = new DoublyLinkedList(new Integer[] { 6, 8, 12 }); + StdOut.println(lst + "[initial]\n"); + + while (!lst.isEmpty()) + { + StdOut.println("removeFirst(): " + lst.removeFirst()); + showList(lst); + } + StdOut.println(); + } + + private static void testRemoveLast() + { + StdOut.println("removeLast:"); + DoublyLinkedList lst = new DoublyLinkedList(new Integer[] { 6, 8, 12 }); + StdOut.println(lst + "[initial]\n"); + + while (!lst.isEmpty()) + { + StdOut.println("removeLast(): " + lst.removeLast()); + showList(lst); + } + StdOut.println(); + } + + private static void testRemove() + { + StdOut.println("remove:"); + DoublyLinkedList lst = new DoublyLinkedList(new Integer[] { 2, 4, 6, 8 }); + StdOut.println(lst + "[initial]\n"); + + int[] k = { 2, -1, 1, 1 }; + + for (int i = 0; i < k.length; i++) + { + StdOut.printf("remove(node(%d)): %d\n", k[i], lst.remove(lst.node(k[i]))); + showList(lst); + } + StdOut.println(); + } + + private static void testInsertBefore() + { + StdOut.println("insertBefore:"); + DoublyLinkedList lst = new DoublyLinkedList(new Integer[] { 2, 4, 6, 8 }); + StdOut.println(lst + "[initial]\n"); + + int[] k = { 3, 2, 1, -1 }, + x = { 10, 12, 14, 16 }; + + for (int i = 0; i < k.length; i++) + { + StdOut.printf("insertBefore(node(%d), %d):\n", k[i], x[i]); + lst.insertBefore(lst.node(k[i]), x[i]); + showList(lst); + } + StdOut.println(); + } + + private static void testInsertAfter() + { + StdOut.println("insertAfter:"); + DoublyLinkedList lst = new DoublyLinkedList(new Integer[] { 1, 3, 5, 7 }); + StdOut.println(lst + "[initial]\n"); + + int[] k = { 2, -2, -1, 1 }, + x = { 9, 11, 13, 15 }; + + for (int i = 0; i < k.length; i++) + { + StdOut.printf("insertAfter(node(%d), %d):\n", k[i], x[i]); + lst.insertAfter(lst.node(k[i]), x[i]); + showList(lst); + } + StdOut.println(); + } + + + /******************* + * Unit test helpers + *******************/ + + private static void showList(DoublyLinkedList lst) + { + StdOut.println(lst); + StdOut.println(lst.reversed() + "[in reverse]"); + if (!lst.isEmpty()) + StdOut.printf("Size: %d, First: %s, Last: %s\n\n", lst.size(), lst.first(), lst.last()); + else + StdOut.printf("Size: %d\n\n", lst.size()); + } + + public static void main(String[] args) + { +// testPrepend(); +// testAppend(); + +// testRemoveFirst(); +// testRemoveLast(); + +// testRemove(); + + testInsertBefore(); + testInsertAfter(); + } +} diff --git a/1-Fundamentals/1-3-BagsQueuesStacks/Evaluate.java b/1-Fundamentals/1-3-BagsQueuesStacks/Evaluate.java new file mode 100644 index 0000000..a72af18 --- /dev/null +++ b/1-Fundamentals/1-3-BagsQueuesStacks/Evaluate.java @@ -0,0 +1,62 @@ + +/************************************************************************* + * Compilation: javac Evaluate.java + * Execution: java Evaluate + * Dependencies: Stack.java + * + * Evaluates (fully parenthesized) arithmetic expressions using + * Dijkstra's two-stack algorithm. + * + * % java Evaluate + * ( 1 + ( ( 2 + 3 ) * ( 4 * 5 ) ) ) + * 101.0 + * + * % java Evaulate + * ( ( 1 + sqrt ( 5 ) ) / 2.0 ) + * 1.618033988749895 + * + * + * + * Remarkably, Dijkstra's algorithm computes the same + * answer if we put each operator *after* its two operands + * instead of *between* them. + * + * % java Evaluate + * ( 1 ( ( 2 3 + ) ( 4 5 * ) * ) + ) + * 101.0 + * + * Moreover, in such expressions, all parentheses are redundant! + * Removing them yields an expression known as a postfix expression. + * 1 2 3 + 4 5 * * + + * + * + *************************************************************************/ + +public class Evaluate { + public static void main(String[] args) { + Stack ops = new Stack(); + Stack vals = new Stack(); + + while (!StdIn.isEmpty()) { + String s = StdIn.readString(); + if (s.equals("(")) ; + else if (s.equals("+")) ops.push(s); + else if (s.equals("-")) ops.push(s); + else if (s.equals("*")) ops.push(s); + else if (s.equals("/")) ops.push(s); + else if (s.equals("sqrt")) ops.push(s); + else if (s.equals(")")) { + String op = ops.pop(); + double v = vals.pop(); + if (op.equals("+")) v = vals.pop() + v; + else if (op.equals("-")) v = vals.pop() - v; + else if (op.equals("*")) v = vals.pop() * v; + else if (op.equals("/")) v = vals.pop() / v; + else if (op.equals("sqrt")) v = Math.sqrt(v); + vals.push(v); + } + else vals.push(Double.parseDouble(s)); + } + StdOut.println(vals.pop()); + } +} diff --git a/1-Fundamentals/1-3-BagsQueuesStacks/EvaluatePostfix.java b/1-Fundamentals/1-3-BagsQueuesStacks/EvaluatePostfix.java new file mode 100644 index 0000000..78fd551 --- /dev/null +++ b/1-Fundamentals/1-3-BagsQueuesStacks/EvaluatePostfix.java @@ -0,0 +1,61 @@ + +/************************************************************************* + * Exercise 1.3.11 + * + * % java EvaluatePostfix + * 1 2 3 + 4 5 * * + + * 101.0 + * + * % java EvaluatePostfix + * 1 5 sqrt + 2.0 / + * 1.618033988749895 + * + * % java EvaluatePostfix + * 12 9 - 105 7 / * + * 45.0 + * + * % java InfixToPostfix | java EvaluatePostfix + * ( 1 + ( ( 2 + 3 ) * ( 4 * 5 ) ) ) + * 101.0 + * + * % java InfixToPostfix | java EvaluatePostfix + * ( ( 1 + sqrt ( 5 ) ) / 2.0 ) + * 1.618033988749895 + * + *************************************************************************/ + +public class EvaluatePostfix +{ + public static void main(String[] args) + { + Stack vals = new Stack(); + + while (!StdIn.isEmpty()) + { + String s = StdIn.readString(); + + if (s.equals("(") || + s.equals(")")) ; + else if (s.equals("+") || + s.equals("-") || + s.equals("*") || + s.equals("/") || + s.equals("sqrt")) + { + double v = vals.pop(); + + if (s.equals("+")) v = vals.pop() + v; + else if (s.equals("-")) v = vals.pop() - v; + else if (s.equals("*")) v = vals.pop() * v; + else if (s.equals("/")) v = vals.pop() / v; + else if (s.equals("sqrt")) v = Math.sqrt(v); + + vals.push(v); + } + else + vals.push(Double.parseDouble(s)); + } + + StdOut.println(vals.pop()); + } +} diff --git a/1-Fundamentals/1-3-BagsQueuesStacks/Ex_1_3_03.java b/1-Fundamentals/1-3-BagsQueuesStacks/Ex_1_3_03.java new file mode 100644 index 0000000..ccb5d1d --- /dev/null +++ b/1-Fundamentals/1-3-BagsQueuesStacks/Ex_1_3_03.java @@ -0,0 +1,74 @@ + +/************************************************************************* + * Simulate a sequence of push and pop operations to find out + * whether a certain sequence of pop's can occur + * + * % java Ex_1_3_03 + * 9 8 7 6 5 4 3 2 1 0 + * true (Unprinted: 0; Stack: [ ]) + * + * 4 3 2 1 0 9 8 7 6 5 + * true (Unprinted: 0; Stack: [ ]) + * + * 4 6 8 7 5 3 2 9 0 1 + * false (Unprinted: 2; Stack: [ 1 0 ]) + * + * 2 5 6 7 4 8 9 3 1 0 + * true (Unprinted: 0; Stack: [ ]) + * + * 4 3 2 1 0 5 6 7 8 9 + * true (Unprinted: 0; Stack: [ ]) + * + * 1 2 3 4 5 6 9 8 7 0 + * true (Unprinted: 0; Stack: [ ]) + * + * 0 4 6 5 3 8 1 7 2 9 + * false (Unprinted: 4; Stack: [ 9 7 2 1 ]) + * + * 1 4 7 9 8 6 5 3 0 2 + * false (Unprinted: 2; Stack: [ 2 0 ]) + * + * 2 1 4 3 6 5 8 7 9 0 + * true (Unprinted: 0; Stack: [ ]) + * + *************************************************************************/ + +public class Ex_1_3_03 +{ + public static void checkSequence(int[] v) + { + Stack s = new Stack(); + int n = v.length; + + int i = 0, j = 0; + while (i < n && j <= n) + { + if (!s.isEmpty() && s.peek() == v[i]) + { + StdOut.print(s.pop() + " "); + i++; + } + else + { + if (j < n) + s.push(j); + j++; + } + } + StdOut.println(); + + StdOut.printf("%s (Unprinted: %d; Stack: [ %s])\n", + i == n && s.isEmpty(), n - i, s); + } + + public static void main(String[] args) + { + String[] a = StdIn.readAll().split("\\s+"); + + int[] v = new int[a.length]; + for (int i = 0; i < a.length; i++) + v[i] = Integer.parseInt(a[i]); + + checkSequence(v); + } +} diff --git a/1-Fundamentals/1-3-BagsQueuesStacks/Ex_1_3_04.java b/1-Fundamentals/1-3-BagsQueuesStacks/Ex_1_3_04.java new file mode 100644 index 0000000..98dab71 --- /dev/null +++ b/1-Fundamentals/1-3-BagsQueuesStacks/Ex_1_3_04.java @@ -0,0 +1,42 @@ + +/************************************************************************* + * + * % java Ex_1_3_04 + * [()]{}{[()()]()} + * true + * + * % java Ex_1_3_04 + * [(]) + * false + * + *************************************************************************/ + +public class Ex_1_3_04 +{ + public static boolean isBalanced(String s) + { + Stack open = new Stack(); + int n = s.length(); + + for (int i = 0; i < n; i++) + { + char c = s.charAt(i); + + if (c == '(' || c == '[' || c == '{') + open.push(c); + else if ((c == ')' && (open.isEmpty() || open.pop() != '(')) || + (c == ']' && (open.isEmpty() || open.pop() != '[')) || + (c == '}' && (open.isEmpty() || open.pop() != '{'))) + return false; + } + + return open.isEmpty(); + } + + public static void main(String[] args) + { + String s = StdIn.readAll().trim(); + + StdOut.println(isBalanced(s)); + } +} diff --git a/1-Fundamentals/1-3-BagsQueuesStacks/Ex_1_3_09.java b/1-Fundamentals/1-3-BagsQueuesStacks/Ex_1_3_09.java new file mode 100644 index 0000000..12ea762 --- /dev/null +++ b/1-Fundamentals/1-3-BagsQueuesStacks/Ex_1_3_09.java @@ -0,0 +1,52 @@ + +/************************************************************************* + * + * % java Ex_1_3_09 + * 1 + 2 ) * 3 - 4 ) * 5 - 6 ) ) ) + * ( ( 1 + 2 ) * ( ( 3 - 4 ) * ( 5 - 6 ) ) ) + * + * % java Ex_1_3_09 + * sqrt 1 + 2 ) ) + * ( sqrt ( 1 + 2 ) ) + * + *************************************************************************/ + +public class Ex_1_3_09 +{ + public static void main(String[] args) + { + Stack ops = new Stack(); + Stack vals = new Stack(); + + while (!StdIn.isEmpty()) + { + String s = StdIn.readString(); + + if (s.equals("(")) ; + else if (s.equals("+") || + s.equals("-") || + s.equals("*") || + s.equals("/") || + s.equals("sqrt")) ops.push(s); + else if (s.equals(")")) + { + String op = ops.pop(); + String v = vals.pop(); + + if (op.equals("+") || + op.equals("-") || + op.equals("*") || + op.equals("/")) + v = String.format("( %s %s %s )", vals.pop(), op, v); + else if (op.equals("sqrt")) + v = String.format("( %s %s )", op, v); + + vals.push(v); + } + else vals.push(s); + //else vals.push(((Double)Double.parseDouble(s)).toString()); + } + + StdOut.println(vals.pop()); + } +} diff --git a/1-Fundamentals/1-3-BagsQueuesStacks/Ex_1_3_29.java b/1-Fundamentals/1-3-BagsQueuesStacks/Ex_1_3_29.java new file mode 100644 index 0000000..e0d9bac --- /dev/null +++ b/1-Fundamentals/1-3-BagsQueuesStacks/Ex_1_3_29.java @@ -0,0 +1,129 @@ +/************************************************************************* + * + * A generic queue, implemented using a *circular* linked list. + * (Exercise 1.3.29) + * + * % java Ex_1_3_29 < tobe.txt + * to be or not to be (2 left on queue) + * + *************************************************************************/ + +import java.util.Iterator; +import java.util.NoSuchElementException; + +public class Ex_1_3_29 implements Iterable { + private int N; + private Node last; + + private class Node { + private Item item; + private Node next; + } + + /** + * Create an empty queue. + */ + public Ex_1_3_29() { + last = null; + } + + /** + * Is the queue empty? + */ + public boolean isEmpty() { + return last == null; + } + + /** + * Return the number of items in the queue. + */ + public int size() { + return N; + } + + /** + * Return the item least recently added to the queue. + * Throw an exception if the queue is empty. + */ + public Item peek() { + if (isEmpty()) throw new RuntimeException("Queue underflow"); + return last.next.item; + } + + /** + * Add the item to the queue. + */ + public void enqueue(Item item) { + Node x = new Node(); + x.item = item; + if (isEmpty()) + x.next = x; + else + { + x.next = last.next; + last.next = x; + } + last = x; + N++; + } + + /** + * Remove and return the item on the queue least recently added. + * Throw an exception if the queue is empty. + */ + public Item dequeue() { + if (isEmpty()) throw new RuntimeException("Queue underflow"); + Item item = last.next.item; + if (last.next == last) + last = null; + else + last.next = last.next.next; + N--; + return item; + } + + /** + * Return string representation. + */ + public String toString() { + StringBuilder s = new StringBuilder(); + for (Item item : this) + s.append(item + " "); + return s.toString(); + } + + + /** + * Return an iterator that iterates over the items on the queue in FIFO order. + */ + public Iterator iterator() { + return new ListIterator(); + } + + private class ListIterator implements Iterator { + private int n = N; + private Node current = last; + + public boolean hasNext() { return n > 0; } + public void remove() { throw new UnsupportedOperationException(); } + + public Item next() { + if (!hasNext()) throw new NoSuchElementException(); + Item item = current.next.item; + current = current.next; + n--; + return item; + } + } + + + public static void main(String[] args) { + Ex_1_3_29 q = new Ex_1_3_29(); + while (!StdIn.isEmpty()) { + String item = StdIn.readString(); + if (!item.equals("-")) q.enqueue(item); + else if (!q.isEmpty()) StdOut.print(q.dequeue() + " "); + } + StdOut.println("(" + q.size() + " left on queue: [ " + q + "])"); + } +} diff --git a/1-Fundamentals/1-3-BagsQueuesStacks/FixedCapacityStack.java b/1-Fundamentals/1-3-BagsQueuesStacks/FixedCapacityStack.java new file mode 100644 index 0000000..cf3d001 --- /dev/null +++ b/1-Fundamentals/1-3-BagsQueuesStacks/FixedCapacityStack.java @@ -0,0 +1,62 @@ +/************************************************************************* + * Compilation: javac FixedCapacityStack.java + * Execution: java FixedCapacityStack + * + * Generic stack implementation with a fixed-size array. + * + * % more tobe.txt + * to be or not to - be - - that - - - is + * + * % java FixedCapacityStack 5 < tobe.txt + * to be not that or be + * + * Remark: bare-bones implementation. Does not do repeated + * doubling or null out empty array entries to avoid loitering. + * + *************************************************************************/ + +import java.util.Iterator; + +public class FixedCapacityStack implements Iterable { + private Item[] a; // holds the items + private int N; // number of items in stack + + // create an empty stack with given capacity + public FixedCapacityStack(int capacity) { + a = (Item[]) new Object[capacity]; // no generic array creation + } + + public boolean isEmpty() { return (N == 0); } + public void push(Item item) { a[N++] = item; } + public Item pop() { return a[--N]; } + public Iterator iterator() { return new ReverseArrayIterator(); } + + + public class ReverseArrayIterator implements Iterator { + private int i = N-1; + + public boolean hasNext() { return i >= 0; } + public Item next() { return a[i--]; } + public void remove() { throw new UnsupportedOperationException(); } + } + + + public static void main(String[] args) { + int max = Integer.parseInt(args[0]); + FixedCapacityStack stack = new FixedCapacityStack(max); + while (!StdIn.isEmpty()) { + String item = StdIn.readString(); + if (!item.equals("-")) stack.push(item); + else if (stack.isEmpty()) StdOut.println("BAD INPUT"); + else StdOut.print(stack.pop() + " "); + } + StdOut.println(); + + // print what's left on the stack + StdOut.print("Left on stack: "); + for (String s : stack) { + StdOut.print(s + " "); + } + StdOut.println(); + } +} diff --git a/1-Fundamentals/1-3-BagsQueuesStacks/FixedCapacityStackOfStrings.java b/1-Fundamentals/1-3-BagsQueuesStacks/FixedCapacityStackOfStrings.java new file mode 100644 index 0000000..de220b1 --- /dev/null +++ b/1-Fundamentals/1-3-BagsQueuesStacks/FixedCapacityStackOfStrings.java @@ -0,0 +1,63 @@ +/************************************************************************* + * Compilation: javac FixedCapacityStackOfStrings.java + * Execution: java FixedCapacityStackOfStrings + * + * Stack of strings implementation with a fixed-size array. + * + * % more tobe.txt + * to be or not to - be - - that - - - is + * + * % java FixedCapacityStackOfStrings 5 < tobe.txt + * to be not that or be + * + * Remark: bare-bones implementation. Does not do repeated + * doubling or null out empty array entries to avoid loitering. + * + *************************************************************************/ + +import java.util.Iterator; + +public class FixedCapacityStackOfStrings implements Iterable { + private String[] a; // holds the items + private int N; // number of items in stack + + // create an empty stack with given capacity + public FixedCapacityStackOfStrings(int capacity) { + a = new String[capacity]; + } + + public boolean isEmpty() { return (N == 0); } + public boolean isFull() { return (N == a.length); } + public void push(String item) { a[N++] = item; } + public String pop() { return a[--N]; } + public Iterator iterator() { return new ReverseArrayIterator(); } + + + public class ReverseArrayIterator implements Iterator { + private int i = N-1; + + public boolean hasNext() { return i >= 0; } + public String next() { return a[i--]; } + public void remove() { throw new UnsupportedOperationException(); } + } + + + public static void main(String[] args) { + int max = Integer.parseInt(args[0]); + FixedCapacityStackOfStrings stack = new FixedCapacityStackOfStrings(max); + while (!StdIn.isEmpty()) { + String item = StdIn.readString(); + if (!item.equals("-")) stack.push(item); + else if (stack.isEmpty()) StdOut.println("BAD INPUT"); + else StdOut.print(stack.pop() + " "); + } + StdOut.println(); + + // print what's left on the stack + StdOut.print("Left on stack: "); + for (String s : stack) { + StdOut.print(s + " "); + } + StdOut.println(); + } +} diff --git a/1-Fundamentals/1-3-BagsQueuesStacks/InfixToPostfix.java b/1-Fundamentals/1-3-BagsQueuesStacks/InfixToPostfix.java new file mode 100644 index 0000000..991e538 --- /dev/null +++ b/1-Fundamentals/1-3-BagsQueuesStacks/InfixToPostfix.java @@ -0,0 +1,52 @@ + +/************************************************************************* + * Exercise 1.3.10 + * + * % java InfixToPostfix + * ( 1 + ( ( 2 + 3 ) * ( 4 * 5 ) ) ) + * 1 2 3 + 4 5 * * + + * + * % java InfixToPostfix + * ( sqrt ( 1 + 2 ) ) + * 1 2 + sqrt + * + *************************************************************************/ + +public class InfixToPostfix +{ + public static void main(String[] args) + { + Stack ops = new Stack(); + Stack vals = new Stack(); + + while (!StdIn.isEmpty()) + { + String s = StdIn.readString(); + + if (s.equals("(")) ; + else if (s.equals("+") || + s.equals("-") || + s.equals("*") || + s.equals("/") || + s.equals("sqrt")) ops.push(s); + else if (s.equals(")")) + { + String op = ops.pop(); + String v = vals.pop(); + + if (op.equals("+") || + op.equals("-") || + op.equals("*") || + op.equals("/")) + v = String.format("%s %s %s", vals.pop(), v, op); + else if (op.equals("sqrt")) + v = String.format("%s %s", v, op); + + vals.push(v); + } + else vals.push(s); + } + + StdOut.println(vals.pop()); + } +} diff --git a/1-Fundamentals/1-3-BagsQueuesStacks/List.java b/1-Fundamentals/1-3-BagsQueuesStacks/List.java new file mode 100644 index 0000000..f729b7f --- /dev/null +++ b/1-Fundamentals/1-3-BagsQueuesStacks/List.java @@ -0,0 +1,649 @@ + +import java.util.Iterator; +import java.util.NoSuchElementException; + +public class List implements Iterable +{ + private int N; + private Node first; + private Node last; + + private class Node + { + private Item item; + private Node next; + } + + public List() + { + first = null; + last = null; + } + + public List(Item[] a) + { + for (Item t : a) + append(t); + } + + public List(Iterable coll) + { + for (Item t : coll) + append(t); + } + + public boolean isEmpty() + { + return first == null; + } + + public int size() + { + return N; + } + + public Item first() + { + if (isEmpty()) throw new RuntimeException("List is empty"); + return first.item; + } + + public Item last() + { + if (isEmpty()) throw new RuntimeException("List is empty"); + return last.item; + } + + public Item removeFirst() + { + if (isEmpty()) throw new RuntimeException("List is empty"); + Item item = first.item; + first = first.next; + N--; + if (isEmpty()) last = null; // to avoid loitering + return item; + } + + public void prepend(Item item) + { + Node x = new Node(); + x.item = item; + if (isEmpty()) { first = x; last = x; } + else { x.next = first; first = x; } + N++; + } + + public void append(Item item) + { + Node x = new Node(); + x.item = item; + if (isEmpty()) { first = x; last = x; } + else { last.next = x; last = x; } + N++; + } + + public String toString() + { + StringBuilder s = new StringBuilder(); + for (Item item : this) + s.append(item + " "); + return s.toString(); + } + + public Iterator iterator() + { + return new ListIterator(); + } + + private class ListIterator implements Iterator + { + 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 item = current.item; + current = current.next; + return item; + } + } + + /***************** + * Exercise 1.3.19 + *****************/ + public Item removeLast() + { + if (isEmpty()) throw new RuntimeException("List is empty"); + if (first == last) return removeFirst(); + Item item = last.item; + + Node prev = null, + curr = first; + while (curr.next != null) + { + prev = curr; + curr = curr.next; + } + prev.next = null; + last = prev; + N--; + + return item; + } + + /***************** + * Exercise 1.3.20 + *****************/ + public Item delete(int k) + { + if (k < 1) return null; + + int i = 1; + Node prev = null, + curr = first; + + while (i < k && curr != null) + { + prev = curr; + curr = curr.next; + i++; + } + + if (curr != null) + { + if (prev == null) + first = curr.next; + else + prev.next = curr.next; + + if (curr.next == null) + last = prev; + + N--; + return curr.item; + } + else + return null; + } + + /************************************* + * Exercise 1.3.21 + * (Renamed from find() to contains()) + *************************************/ + public boolean contains(Item item) + { + Node curr = first; + while (curr != null && !curr.item.equals(item)) + curr = curr.next; + return curr != null; + } + + /***************** + * Exercise 1.3.26 + *****************/ + public void remove(Item item) + { + List idx = new List(); + int i = 1; + + for (Item x : this) + { + if (x.equals(item)) + idx.prepend(i); + i++; + } + + for (int k : idx) + delete(k); + } + + /*************************************** + * Recursive solution to Exercise 1.3.26 + ***************************************/ + public void removeRec(Item item) + { + first = remove_Node(first, item); + setLastAndN(); + } + + private Node remove_Node(Node node, Item item) + { + if (node != null) + { + Node rest = remove_Node(node.next, item); + + if (node.item.equals(item)) + return rest; + else + { + node.next = rest; + return node; + } + } + else + return null; + } + + private void setLastAndN() + { + last = first; + N = 0; + if (first != null) + { + N++; + while (last.next != null) + { + last = last.next; + N++; + } + } + } + + + /********************* + * Operations on nodes + *********************/ + + public Node node(int k) + { + if (k < 1) return null; + + int i = 1; + Node curr = first; + + while (i < k && curr != null) + { + curr = curr.next; + i++; + } + + return curr; + } + + public Node createNode(Item item) + { + Node node = new Node(); + node.item = item; + return node; + } + + /***************** + * Exercise 1.3.24 + *****************/ + public void removeAfter(Node node) + { + if (node != null && node.next != null) + { + if (node.next.next == null) + last = node; + node.next = node.next.next; + N--; + } + } + + /***************** + * Exercise 1.3.25 + *****************/ + public void insertAfter(Node a, Node b) + { + if (a != null && b != null) + { + if (last == a) + last = b; + b.next = a.next; + a.next = b; + N++; + } + } + + /************************************************* + * Exercise 1.3.27 + * Type 'Item' must implement interface Comparable + *************************************************/ + public Item max(Node node) + { + if (node == null) throw new RuntimeException("List is empty"); + return max(node, null); + } + + public Item max(Node node, Item def) + { + if (node == null) + return def; + + Item max = node.item; + Node curr = node; + + while (curr.next != null) + { + curr = curr.next; + if (((Comparable)max).compareTo(curr.item) < 0) + max = curr.item; + } + + return max; + } + + /************************************************* + * Exercise 1.3.28 + * (recursive variant of Exercise 1.3.27) + * Type 'Item' must implement interface Comparable + *************************************************/ + public Item maxRec(Node node, Item def) + { + if (node == null) + return def; + else + return maxRec(node); + } + + public Item maxRec(Node node) + { + if (node == null) throw new RuntimeException("List is empty"); + + if (node.next == null) + return node.item; + else + { + Item maxTail = maxRec(node.next); + return ((Comparable)node.item).compareTo(maxTail) > 0 ? node.item : maxTail; + } + } + + /***************** + * Exercise 1.3.30 + *****************/ + public void reverse() + { + first = reverse(first); + setLastAndN(); + } + + public Node reverse(Node node) + { + Node srcFirst = node, + destFirst = null; + while (srcFirst != null) + { + Node next = srcFirst.next; + srcFirst.next = destFirst; + destFirst = srcFirst; + srcFirst = next; + } + + return destFirst; + } + + /*************************************** + * Recursive solution to Exercise 1.3.30 + ***************************************/ + public void reverseRec() + { + first = reverseRec(first); + setLastAndN(); + } + + private Node reverseRec(Node node) + { + return reverseRec(node, null); + } + + private Node reverseRec(Node srcFirst, Node destFirst) + { + if (srcFirst == null) + return destFirst; + else + { + Node next = srcFirst.next; + srcFirst.next = destFirst; + return reverseRec(next, srcFirst); + } + } + + + /************ + * Unit tests + ************/ + + private static void testBaseMethods() + { + int[] a = { 2, 4, 6, 8, 10, 12 }; + + List lst = new List(); + for (int i = 0; i < a.length; i++) + lst.append(a[i]); + showList(lst); + + lst = new List(); + for (int i = 0; i < a.length; i++) + lst.prepend(a[i]); + showList(lst); + + StdOut.println("removeFirst: " + lst.removeFirst()); + showList(lst); + } + + private static void testRemoveLast() + { + List lst = new List(new Integer[] { 6, 8, 10, 12 }); + showList(lst); + + while (!lst.isEmpty()) + { + StdOut.println("removeLast: " + lst.removeLast()); + showList(lst); + } + } + + private static void testDelete() + { + List lst = new List(new Integer[] { 2, 4, 6, 8, 10, 12 }); + showList(lst); + + StdOut.printf("delete(%d): %s\n", 5, lst.delete(5)); + showList(lst); + + StdOut.printf("delete(%d): %s\n", 1, lst.delete(1)); + showList(lst); + + StdOut.printf("delete(%d): %s\n", 4, lst.delete(4)); + showList(lst); + + StdOut.printf("delete(%d): %s\n", 8, lst.delete(8)); + showList(lst); + + StdOut.printf("delete(%d): %s\n", 0, lst.delete(0)); + showList(lst); + + while (!lst.isEmpty()) + { + StdOut.printf("delete(%d): %s\n", 1, lst.delete(1)); + showList(lst); + } + } + + private static void testContains() + { + Integer[] a = { 4, 6, 10, 12 }; + List lst = new List(a); + showList(lst); + + StdOut.printf("contains(%d): %s\n", 0, lst.contains(0)); + + for (int i = 0; i < a.length; i++) + StdOut.printf("contains(%d): %s\n", a[i], lst.contains(a[i])); + } + + private static void testRemove() + { + for (int k = 0; k < 8; k++) + { + List lst1 = randomList(20, 0, 5); + List lst2 = new List(lst1); + StdOut.println(lst1); + StdOut.println(); + + int n = StdRandom.uniform(0, 5); + + StdOut.printf("remove(%d):\n", n); + lst1.remove(n); + showList(lst1); + + StdOut.printf("removeRec(%d):\n", n); + lst2.removeRec(n); + showList(lst2); + StdOut.println(); + } + } + + private static void testReverse() + { + int n = 10; + Integer[] a = new Integer[n]; + for (int i = 0; i < n; i++) + a[i] = 2 * (i + 1); + + testReverse(new List(a)); + StdOut.println(); + + testReverse(randomList(20, 0, 10)); + StdOut.println(); + + testReverse(new List(new Integer[] { 37 })); + StdOut.println(); + + testReverse(new List(new Integer[] { })); + StdOut.println(); + } + + private static void testReverse(List lst) + { + List lst1 = lst; + List lst2 = new List(lst1); + StdOut.println(lst1); + + StdOut.println("reverse():"); + lst1.reverse(); + StdOut.println(lst1); + + StdOut.println("reverseRec():"); + lst2.reverseRec(); + StdOut.println(lst2); + } + + private static void testNode() + { + List lst = new List(new Integer[] { 2, 6, 12 }); + showList(lst); + + for (int i = -1; i <= 4; i++) + StdOut.printf("node(%d): %s\n", i, lst.node(i) != null ? lst.node(i).item : null); + } + + private static void testRemoveAfter() + { + List lst = new List(new Integer[] { 2, 6, 8, 10, 12 }); + showList(lst); + + int[] k = { 0, 2, 1, 5, 3, 2, 1 }; + + for (int i = 0; i < k.length; i++) + { + StdOut.printf("removeAfter(node(%d)):\n", k[i]); + lst.removeAfter(lst.node(k[i])); + showList(lst); + } + } + + private static void testInsertAfter() + { + List lst = new List(new Integer[] { 2, 6, 10, 12 }); + showList(lst); + + StdOut.printf("insertAfter(node(%d), null):\n", 1); + lst.insertAfter(lst.node(1), null); + showList(lst); + + int ia = 1, + b = 3; + StdOut.printf("insertAfter(node(%d), createNode(%d)):\n", ia, b); + lst.insertAfter(lst.node(ia), lst.createNode(b)); + showList(lst); + + ia = 5; + b = 25; + StdOut.printf("insertAfter(node(%d), createNode(%d)):\n", ia, b); + lst.insertAfter(lst.node(ia), lst.createNode(b)); + showList(lst); + } + + private static void testMax() + { + for (int k = 0; k < 8; k++) + { + List lst = randomList(10, 100, 1000); + StdOut.println(lst); + + StdOut.printf("max(): %d\n", lst.max(lst.node(1))); + StdOut.printf("maxRec(): %d\n\n", lst.maxRec(lst.node(1))); + } + } + + + /******************* + * Unit test helpers + *******************/ + + public static void showList(List lst) + { + StdOut.println(lst); + if (!lst.isEmpty()) + StdOut.printf("Size: %d, First: %s, Last: %s\n\n", lst.size(), lst.first(), lst.last()); + else + StdOut.printf("Size: %d\n\n", lst.size()); + } + + private static List randomList(int n, int a, int b) + { + Integer[] r = new Integer[n]; + for (int i = 0; i < n; i++) + r[i] = StdRandom.uniform(a, b); + return new List(r); + } + + public static void main(String[] args) + { + testBaseMethods(); + StdOut.println(); + + testRemoveLast(); + StdOut.println(); + + testDelete(); + StdOut.println(); + + testContains(); + StdOut.println(); + + testNode(); + StdOut.println(); + + testRemoveAfter(); + StdOut.println(); + + testInsertAfter(); + StdOut.println(); + + testRemove(); + StdOut.println(); + + testMax(); + StdOut.println(); + + testReverse(); + StdOut.println(); + } +} diff --git a/1-Fundamentals/1-3-BagsQueuesStacks/Parentheses.java b/1-Fundamentals/1-3-BagsQueuesStacks/Parentheses.java new file mode 100644 index 0000000..6ead6dd --- /dev/null +++ b/1-Fundamentals/1-3-BagsQueuesStacks/Parentheses.java @@ -0,0 +1,58 @@ +/************************************************************************* + * Compilation: javac Parentheses.java + * Execution: java Parentheses + * Dependencies: In.java Stack.java + * + * Reads in a text file and checks to see if the parentheses are balanced. + * + * % java Parentheses + * [()]{}{[()()]()} + * true + * + * % java Parentheses + * [(]) + * false + * + *************************************************************************/ + +public class Parentheses { + private static final char LEFT_PAREN = '('; + private static final char RIGHT_PAREN = ')'; + private static final char LEFT_BRACE = '{'; + private static final char RIGHT_BRACE = '}'; + private static final char LEFT_BRACKET = '['; + private static final char RIGHT_BRACKET = ']'; + + public static boolean isBalanced(String s) { + Stack stack = new Stack(); + for (int i = 0; i < s.length(); i++) { + if (s.charAt(i) == LEFT_PAREN) stack.push(LEFT_PAREN); + if (s.charAt(i) == LEFT_BRACE) stack.push(LEFT_BRACE); + if (s.charAt(i) == LEFT_BRACKET) stack.push(LEFT_BRACKET); + + if (s.charAt(i) == RIGHT_PAREN) { + if (stack.isEmpty()) return false; + if (stack.pop() != LEFT_PAREN) return false; + } + + else if (s.charAt(i) == RIGHT_BRACE) { + if (stack.isEmpty()) return false; + if (stack.pop() != LEFT_BRACE) return false; + } + + else if (s.charAt(i) == RIGHT_BRACKET) { + if (stack.isEmpty()) return false; + if (stack.pop() != LEFT_BRACKET) return false; + } + } + return stack.isEmpty(); + } + + + public static void main(String[] args) { + In in = new In(); + String s = in.readAll().trim(); + StdOut.println(isBalanced(s)); + } +} + diff --git a/1-Fundamentals/1-3-BagsQueuesStacks/Stats.java b/1-Fundamentals/1-3-BagsQueuesStacks/Stats.java new file mode 100644 index 0000000..d1fc006 --- /dev/null +++ b/1-Fundamentals/1-3-BagsQueuesStacks/Stats.java @@ -0,0 +1,42 @@ +/************************************************************************* + * Compilation: javac Stats.java + * Execution: java Stats < input.txt + * Dependencies: Bag.java StdIn.java StdOut.java + * + * Reads in a sequence of real numbers from standard input and + * computes their mean and standard deviation. + * + * % java Stats + * 100 99 101 120 98 107 109 81 101 90 + * Mean: 100.60 + * Std dev: 10.51 + * + *************************************************************************/ + +public class Stats { + public static void main(String[] args) { + + // read in numbers + Bag numbers = new Bag(); + while (!StdIn.isEmpty()) { + numbers.add(StdIn.readDouble()); + } + int N = numbers.size(); + + // compute mean + double sum = 0.0; + for (double x : numbers) + sum += x; + double mean = sum/N; + + // compute standard deviation + sum = 0.0; + for (double x : numbers) { + sum += (x - mean) * (x - mean); + } + double std = Math.sqrt(sum/(N-1)); + + StdOut.printf("Mean: %.2f\n", mean); + StdOut.printf("Std dev: %.2f\n", std); + } +}