예제 #1
0
 public Stack<T> concat(Stack<T> stack) {
   Stack<T> rv = this;
   for (T elt : stack) {
     rv = rv.push(elt);
   }
   return rv;
 }
예제 #2
0
 // Too bad Java doesn't support generic arrays or varargs
 public static Stack<String> makeName(String... strings) {
   Stack<String> rv = Stack.<String>emptyInstance();
   for (int i = strings.length - 1; i >= 0; i--) {
     rv = rv.push(strings[i]);
   }
   return rv;
 }
예제 #3
0
 public Stack<T> addUnique(Stack<T> stack) {
   Stack<T> rv = this;
   for (T elt : stack) {
     if (rv.contains(elt)) continue;
     rv = rv.push(elt);
   }
   return rv;
 }
예제 #4
0
 public int compare(Stack<T> arg0, Stack<T> arg1) {
   if (arg0.isEmpty()) {
     return arg1.isEmpty() ? 0 : -1;
   } else {
     if (arg1.isEmpty()) return 1;
     int rv = arg0.head().compareTo(arg1.head());
     return rv == 0 ? compare(arg0.tail(), arg1.tail()) : rv;
   }
 }
예제 #5
0
 public T next() {
   T rv = stack.head();
   stack = stack.tail();
   return rv;
 }
예제 #6
0
 public boolean hasNext() {
   return !stack.isEmpty();
 }
예제 #7
0
  // Warning, uses equals to test for containment.
  public boolean contains(Stack<T> stack) {
    if (stack.isEmpty()) return true;
    if (isEmpty()) return false; // stack is not empty

    return head().equals(stack.head()) ? tail().contains(stack.tail()) : false;
  }
예제 #8
0
public abstract class Stack<T> implements Iterable<T> {
  public static final String DEFAULT_DELIM = ", ";

  public abstract boolean isEmpty();

  public Stack<T> push(T elt) {
    return new Element<T>(elt, this);
  }

  public Stack<T> concat(Stack<T> stack) {
    Stack<T> rv = this;
    for (T elt : stack) {
      rv = rv.push(elt);
    }
    return rv;
  }

  public Stack<T> addUnique(Stack<T> stack) {
    Stack<T> rv = this;
    for (T elt : stack) {
      if (rv.contains(elt)) continue;
      rv = rv.push(elt);
    }
    return rv;
  }

  public abstract T head();

  public abstract Stack<T> tail();

  public abstract boolean contains(T elt);

  public abstract int size();
  // returns a stack where the first occurrence of the given element is removed using equals
  public abstract Stack<T> remove(T elt);

  public abstract Stack<T> reverse();

  protected abstract Stack<T> reverseImpl(Stack<T> stack);

  @SuppressWarnings("unchecked")
  public static <T> Stack<T> emptyInstance() {
    return (Stack<T>) Empty.instance;
  }

  // Warning, uses equals to test for containment.
  public boolean contains(Stack<T> stack) {
    if (stack.isEmpty()) return true;
    if (isEmpty()) return false; // stack is not empty

    return head().equals(stack.head()) ? tail().contains(stack.tail()) : false;
  }

  public Iterator<T> iterator() {
    return new StackIterator<T>(this);
  }

  public String toString() {
    return toString(DEFAULT_DELIM);
  }

  public String toString(String delim) {
    return Joiner.join(this, delim);
  }

  private static class StackIterator<T> implements Iterator<T> {
    Stack<T> stack;

    public StackIterator(Stack<T> stack) {
      this.stack = stack;
    }

    public boolean hasNext() {
      return !stack.isEmpty();
    }

    public T next() {
      T rv = stack.head();
      stack = stack.tail();
      return rv;
    }

    public void remove() {
      throw new UnsupportedOperationException();
    }
  }

  // Singleton
  public static class Empty<T> extends Stack<T> {
    public static final Empty<?> instance = new Empty<Object>();

    public boolean isEmpty() {
      return true;
    }

    public T head() {
      throw new UnsupportedOperationException();
    }

    public Stack<T> tail() {
      throw new UnsupportedOperationException();
    }

    public boolean contains(T elt) {
      return false;
    }

    public int size() {
      return 0;
    }

    public Stack<T> remove(T elt) {
      throw new java.util.NoSuchElementException();
    }

    public Stack<T> reverse() {
      return this;
    }

    protected Stack<T> reverseImpl(Stack<T> stack) {
      return stack;
    }
  }

  public static class Element<T> extends Stack<T> {
    public final T head;
    public final Stack<T> tail;

    public Element(T head, Stack<T> tail) {
      this.head = head;
      this.tail = tail;
    }

    public T head() {
      return head;
    }

    public Stack<T> tail() {
      return tail;
    }

    public boolean isEmpty() {
      return false;
    }

    public boolean contains(T elt) {
      return head.equals(elt) || tail.contains(elt);
    }

    public int size() {
      return 1 + tail.size();
    }

    public Stack<T> remove(T elt) {
      if (head.equals(elt)) return tail;

      return tail.remove(elt).push(head);
    }

    public Stack<T> reverse() {
      return reverseImpl(Stack.<T>emptyInstance());
    }

    protected Stack<T> reverseImpl(Stack<T> stack) {
      return tail.reverseImpl(stack.push(head));
    }
  }

  public static final Comparator<Stack<String>> STRING_COMP =
      Stack.<String>lexicalComparatorInstance();

  @SuppressWarnings("unchecked")
  public static <T extends Comparable<? super T>> Comparator<Stack<T>> lexicalComparatorInstance() {
    return LexicalStackComparator.INSTANCE;
  }

  public static <T> Stack<T> makeStack(Iterator<T> it) {
    if (!it.hasNext()) return Stack.<T>emptyInstance();

    T next = it.next();
    return Stack.<T>makeStack(it).push(next);
  }

  public static <T> Stack<T> makeStack(Iterable<T> iter) {
    return Stack.<T>makeStack(iter.iterator());
  }

  // Too bad Java doesn't support generic arrays or varargs
  public static Stack<String> makeName(String... strings) {
    Stack<String> rv = Stack.<String>emptyInstance();
    for (int i = strings.length - 1; i >= 0; i--) {
      rv = rv.push(strings[i]);
    }
    return rv;
  }

  public static class LexicalStackComparator<T extends Comparable<? super T>>
      implements Comparator<Stack<T>> {
    @SuppressWarnings("rawtypes")
    private static final LexicalStackComparator INSTANCE = new LexicalStackComparator();

    private LexicalStackComparator() {}

    public int compare(Stack<T> arg0, Stack<T> arg1) {
      if (arg0.isEmpty()) {
        return arg1.isEmpty() ? 0 : -1;
      } else {
        if (arg1.isEmpty()) return 1;
        int rv = arg0.head().compareTo(arg1.head());
        return rv == 0 ? compare(arg0.tail(), arg1.tail()) : rv;
      }
    }
  }
}
예제 #9
0
 public static <T> Stack<T> makeStack(Iterable<T> iter) {
   return Stack.<T>makeStack(iter.iterator());
 }
예제 #10
0
  public static <T> Stack<T> makeStack(Iterator<T> it) {
    if (!it.hasNext()) return Stack.<T>emptyInstance();

    T next = it.next();
    return Stack.<T>makeStack(it).push(next);
  }
예제 #11
0
 protected Stack<T> reverseImpl(Stack<T> stack) {
   return tail.reverseImpl(stack.push(head));
 }
예제 #12
0
 public Stack<T> reverse() {
   return reverseImpl(Stack.<T>emptyInstance());
 }
예제 #13
0
    public Stack<T> remove(T elt) {
      if (head.equals(elt)) return tail;

      return tail.remove(elt).push(head);
    }
예제 #14
0
 public int size() {
   return 1 + tail.size();
 }
예제 #15
0
 public boolean contains(T elt) {
   return head.equals(elt) || tail.contains(elt);
 }