OutOfBoundsException into stack - java

I have a problem with ArrayIndexOutOfBoundsException it is always appears in my program. How I can go into try{}?
#Override
public Object pop() {
if (stackIsEmpty()) {
System.err.println("underflow");
return null;
} else {
try {
Object temp = stack[top];
stack[top--] = null;
System.out.println("top is " + top);
return temp;
} catch (ArrayIndexOutOfBoundsException e) {
return "exception";
}
}
}
added code of the rest class( I have the comparison with -1 into stackisEmpty()):
public class ArrayStackImpl implements ArrayStack {
private int top = -1;
private int maxLength;
public Object stack[] = new Object[maxLength];
public ArrayStackImpl(int maxLength) {
this.maxLength = maxLength;
}
#Override
public boolean stackIsEmpty() {
return (top < 0);
}
#Override
public void push(Object o) {
if ((top >= maxLength - 1))
System.err.println("overflow");
else
try {
stack[++top] = o;
} catch (ArrayIndexOutOfBoundsException e) {
}
}

On popping of a non-empty stack top might become -1 (for "empty stack"). So
private int top = -1;
public boolean stackIsEmpty() {
return top < 0; // != -1
}
Do the field initialisation in your constructor. Before that maxlength is not initialized, and 0.
Furthermore you do not need maxlength as field. stack.length == maxlength.
public Object[] stack;
public ArrayStackImpl(int maxLength) {
stack = new Object[maxLength];
(I used the more conventional notation Object[].)

Check top is initialized to -1. Don't catch ArrayIndexOutOfBoundsException, find out why. Also, your stackIsEmpty should check if top equals -1.

Related

Custom treeSet class, how to write iterator

I am trying to create my own binary search tree. But I can't think of any way to implement a working iterator that has hasNext(), next().
I got the idea the only way to traverse a Binary search tree was through recursion. But how could I possibly save a recursion call if I am trying to use next, so it resumes when next gets called again and returns the value?
Is there any other way
import java.util.Iterator;
public class TreeWordSet implements WordSetInterface {
private BST root = null;
private class BST {
Word value;
BST left = null;
BST right = null;
BST(Word word) {
value = word;
}
void add(Word newWord) {
if (newWord.compareTo(value) < 0) {
if(left == null) {
left = new BST(newWord);
} else {
left.add(newWord);
}
} else if (newWord.compareTo(value) > 0) {
if (right == null) {
right = new BST(newWord);
} else {
right.add(newWord);
}
}
}
}
#Override
public void add(Word word) {
if (root == null) {
root = new BST(word);
} else {
root.add(word);
}
}
#Override
public boolean contains(Word word) {
return false;
}
#Override
public int size() {
return 0;
}
private class TreeWordSetIterator implements Iterator<Word> {
#Override
public boolean hasNext() {
return false;
}
#Override
public Word next() {
return null;
}
}
#Override
public Iterator<Word> iterator() {
return new TreeWordSetIterator();
}
}
If this is an exercise for the purpose of learning, maybe the best way is to just go look how TreeSet does it. If this is an exercise for production use, stop it right here right now and extend TreeSet if you really need to.
I solved it this way, it's not glamourous. Until someone can provide a better solution
private class TreeWordSetIterator implements Iterator<Word> {
Word arr[] = new Word[size()];
int i = 0;
TreeWordSetIterator(){
traverse(root);
i = 0;
}
private void traverse(BST currentNode) {
if (currentNode == null) {
return;
}
traverse(currentNode.left);
arr[i] = currentNode.value;
i++;
traverse(currentNode.right);
}
#Override
public boolean hasNext() {
if (i < size()) {
return true;
} else {
return false;
}
}
#Override
public Word next() {
Word current = arr[i];
i++;
return current;
}
}

how to return Next and previous object in ArrayList

I'm creating methods that will be used for buttons one that will return the next Photo object in my array and when it gets to the end will start over moving through the list. The other that will get the previous Photo Object and will start at the end when it reaches the beginning
My issue is that the loop always returns true and if I use listIterator.next I get an error, my class also implements collection if that helps any
public Photo next() {
ListIterator<Photo> listIterator = PhotoAlbum.photo.listIterator();
if (this.size() == 0) {
return null;
}
if (listIterator.hasNext()) {
Photo output = listIterator.next();
return output;
}
return PhotoAlbum.photo.get(0);
}
public Photo previous() {
ListIterator<Photo> listIterator = PhotoAlbum.photo.listIterator();
if (this.size() == 0) {
return null;
}
if (listIterator.hasPrevious()) {
return listIterator.previous();
}
return PhotoAlbum.photo.get(this.size()-1);
}
You should store the current index of the photo inside a variable.
private int currentPhotoIndex = 0;
Then your functions will increment/decrement it depending on the operation
private int currentPhotoIndex = 0;
public Photo next() {
if (this.size() == 0) {
return null;
}
if (this.currentPhotoIndex < this.size()) {
this.currentPhotoIndex++;
} else {
this.currentPhotoIndex = 0;
}
//I think here it should be: return this.get(currentPhotoIndex), but I sticked to your code
return PhotoAlbum.photo.get(currentPhotoIndex);
}
public Photo previous() {
if (this.size() == 0) {
return null;
}
if (this.currentPhotoIndex > 0) {
this.currentPhotoIndex--;
} else {
this.currentPhotoIndex = this.size() - 1;
}
//I think here it should be: return this.get(currentPhotoIndex), but I sticked to your code
return PhotoAlbum.photo.get(currentPhotoIndex);
}
You can do it simple using ListIterator, here is an example of that.
public class Main {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
names.add("Thomas");
names.add("Andrew");
names.add("Ivan");
ListIterator li = names.listIterator();
while(li.hasNext()) {
System.out.println(li.next());
}
while(li.hasPrevious()) {
System.out.println(li.previous());
}
}
}
Of course that is only a simple example, but you can adapt it to your needs.

What is wrong with this code? It won't run

public class StackSimple{
private long capacity=1000;//maximum size of array
private int idx_top;
private Object data[];
public StackSimple(int capacity)
{
idx_top=-1;
this.capacity=capacity;
data = new Object[capacity];
}
public boolean isEmpty(){
return(idx_top<0);
}
public boolean isFull(){
return(idx_top>=capacity-1);
}
public int size()
{
return idx_top+1;
}
public boolean push(Object x){
if (isFull()){
throw new IllegalArgumentException("ERROR:Stack Overflow.Full Stack");
}
else
{`enter code here`data[++idx_top]=x;
return true;
}
}
public Object pop(){
if(isEmpty())
throw new IllegalArgumentException("ERROR:Stack Underflow.Empty Stack.");
else{
return data[idx_top--];
}
}
public Object top(){
if (isEmpty())
throw new IllegalArgumentException("ERROR:Stack Underflow.Empty Stack.");
else{
return data[idx_top];
}
}
public void print()
{`
for (int i=size()-1;i>=0;i--)
System.out.println(data[i]);
}
}
public class Stack_Exercise {
public static void main(String[] args) {
StackSimple s = new StackSimple(capacity:3);//error shows here
s.push(x:"books");`enter code here`
s.push(x:"something");
s.push(x:"200");
s.print();
System.out.println("Size=" +s.size());
}
}
Why doesn't this work?
Why does it say invalid statement while creating the StackSimple object? The problem is in the main class while running it. There are errors while pushing the elements.
Error while compiling
When passing parameters to a function you just pass the values.
In your case not StackSimple(capacity:3) but just StackSimple(3)
First question, which version of Java are you using.
Second, in Java you should be passing as a variable instead of StackSimple(capacity:3). Change your main method to below, here is my recommendation:
StackSimple s = new StackSimple(3);
s.push("books");
s.push("something");
s.push("200");
s.print();
System.out.println("Size=" +s.size());
You are not at all pushing the value in the stack, your pusch function is not working as it is expected to work.
Here is the correct program.
class StackSimple {
private long capacity = 1000;// maximum size of array
private int idx_top;
private Object data[];
public StackSimple(int capacity) {
idx_top = -1;
this.capacity = capacity;
data = new Object[capacity];
}
public boolean isEmpty() {
return (idx_top < 0);
}
public boolean isFull() {
return (idx_top >= capacity - 1);
}
public int size() {
return idx_top + 1;
}
public boolean push(Object x) {
if (isFull()) {
throw new IllegalArgumentException("ERROR:Stack Overflow.Full Stack");
} else {
data[++idx_top] = x;
return true;
}
}
public Object pop() {
if (isEmpty())
throw new IllegalArgumentException("ERROR:Stack Underflow.Empty Stack.");
else {
return data[idx_top--];
}
}
public Object top() {
if (isEmpty())
throw new IllegalArgumentException("ERROR:Stack Underflow.Empty Stack.");
else {
return data[idx_top];
}
}
public void print() {
for (int i = size() - 1; i >= 0; i--)
System.out.println(data[i]);
}
}
public class test {
public static void main(String[] args) {
StackSimple s = new StackSimple(3);// error shows here
s.push("books");
s.push("something");
s.push("200");
s.print();
System.out.println("Size=" + s.size());
}
}

Implement two stacks using one array

I still don't know WHERE to implement the second Stack. Am i supposed to make another class? I'm not quite sure how to finish up. I'll keep searching. Any help would be appreciated! I also can't tell if my pop() method is working or not. I printed out the stack.
Output:
true
5
10
15
20
25
30
35
false
public class twoStack {
int maxSize = 10;
int top;
int top2;
int arr[];
public twoStack(int x)
{
maxSize = x;
arr = new int[maxSize];
top = 0;
top2 = maxSize;
}
//push pop empty peek
public boolean empty()
{
if(top == 0)
{
return true;
}
else
{
return false;
}
}
public boolean empty2()
{
if(top2 == maxSize)
{
return true;
}
else
{
return false;
}
}
public void push(int x)
{
if (top<maxSize)
{
arr[top] = 10;
top++;
}
else
{
System.out.print("Stack overflow");
}
}
public void push2(int x)
{
if(top2<0)
{
arr[top2] = 0;
top2--;
}
else
{
System.out.print("Stack Overflow");
}
}
#SuppressWarnings("null")
public Object pop()
{
if(!this.empty())
{
int temp = (int) this.peek();
arr[top-1]=(Integer) null ;
top--;
return temp;
}
else
{
return null;
}
}
#SuppressWarnings("null")
public Object pop2()
{
if(!this.empty2())
{
int temp = (int) this.peek();
arr[top+1]=(Integer) null;
top++;
return temp;
}
else
{
return null;
}
}
public Object peek()
{
if (!this.empty())
{
return arr[top-1];
}
else
{
return null;
}
}
public Object peek2()
{
if(!this.empty2())
{
return arr[top+1];
}
else
{
return null;
}
}
}
//mainstack
package twoStack;
import java.util.Stack;
public class mainStack {
public static void main(String[] args) {
//MM(main method)
Stack<Integer> myStack= new Stack<Integer>();
System.out.println(myStack.empty());
myStack.push(5);
System.out.println(myStack.peek());
myStack.push(10);
System.out.println(myStack.pop());
myStack.push(15);
System.out.println(myStack.peek());
myStack.push(20);
System.out.println(myStack.peek());
myStack.push(25);
System.out.println(myStack.pop());
myStack.push(30);
System.out.println(myStack.peek());
myStack.push(35);
System.out.println(myStack.peek());
myStack.push(40);
System.out.println(myStack.empty());
}
}
If you have one array of maximal size, two stacks are possible: as a stack grows from a fixed position in some direction and shrinks there too. The start position is fixed.
pick a fixed bottom index for both stacks
start the first stack from that bottom index upwards ++
start the second stack from that bottom index downwards --
Use the full unallocated room, that is ++ and -- modulo the array size.
If both stack pointers meet, both stacks are full.
I wonder whether I have told too much. Maybe just that a stack might grow upwards and downwards, and around (modulo), and has a fixed start.
Try this:
public class TwooStacksInAnArray {
int[] array;
int headOne,headTwo;
public TwooStacksInAnArray(int n){
array=new int[n];
headOne=-1;
headTwo=array.length;
}
public void pushX(int data){
if(headTwo-headOne>1)
array[++headOne]=data;
else
System.out.println("No space to fill data on stack1 ");
}
public void pushY(int data){
if(headTwo-headOne>1)
array[--headTwo]=data;
else
System.out.println("No space to fill data on stack2 ");
}
public int popX(){
if(headOne>-1)
return array[headOne--];
else {
System.out.println("underflow stack1");
return 0;
}
}
public int popY(){
if(headTwo<array.length)
return array[headTwo++];
else{
System.out.println("underflow stack2");
return 0;
}
}
public boolean isEmptyX(){
return (headOne==-1);
}
public boolean isEmptyY(){
return (headTwo==(array.length));
}
}
public class stackDriver {
public static void main(String[] args) {
// TODO Auto-generated method stub
TwooStacksInAnArray twostack=new TwooStacksInAnArray(10);
twostack.pushX(10);
twostack.pushY(9);
twostack.pushX(100);
twostack.pushY(99);
System.out.println("Poped element from stack 1: "+twostack.popX());
System.out.println("Poped element from stack 2: "+twostack.popY());
}
}

Inexplicable Issue with Add Method of a Simple Binary Tree

My binary tree looks pretty close to my class materials, but when I print to the console or check for contains(), any adds I'm doing aren't registered.
I don't have a great understanding of static and the debugger is giving me a hint about making a static reference to non-static variable overallRoot, but everything compiles without error or warning in eclipse.
public class BSTSimpleSet<E extends Comparable<E>> implements SimpleSet<E> {
private GTNode<E> overallRoot;
private int size;
public static void main(String[] args) {
BSTSimpleSet<Integer> main = new BSTSimpleSet<Integer>(2);
main.toString();
main.add(3);
main.toString();
main.add(4);
main.toString();
main.add(5);
main.toString();
System.out.print(main.contains(3));
}
public BSTSimpleSet() {
size = 0;
}
public BSTSimpleSet(E input) {
overallRoot = new GTNode<E>(input);
size = 1;
}
public boolean add(E e) {
return add(e, overallRoot);
}
private boolean add(E e, GTNode<E> root) {
if (root == null) {
root = new GTNode<E>(e);
size++;
return true;
} else {
int compare = e.compareTo(root.data);
if (compare == 0) {
return false;
} else if (compare < 0) {
return add(e, root.left);
} else {
return add(e, root.right);
}
}
}
public void clear() {
overallRoot = null;
}
public boolean contains(E e) {
return contains(e, overallRoot);
}
private boolean contains(E e, GTNode<E> root) {
if (root == null) {
return false;
} else {
int compare = e.compareTo(root.data);
if (compare == 0) {
return true;
} else if (compare < 0) {
return contains(e, root.left);
} else {
return contains(e, root.right);
}
}
}
public boolean isEmpty() {
if (overallRoot == null) {
return false;
} else {
return true;
}
}
public int size() {
return size;
}
public String toString() {
this.toString(overallRoot, 0);
return null;
}
private void toString(GTNode<E> root, int level) {
if (root != null) {
for (int i = 0; i < level; i++) {
System.out.print(" ");
}
System.out.println(root.data);
toString(root.left, level + 1);
toString(root.right, level + 1);
} else {
for (int i = 0; i < level; i++) {
System.out.print(" ");
}
System.out.println("_");
}
}
private static class GTNode<E extends Comparable<E>> {
public E data;
public GTNode<E> left;
public GTNode<E> right;
public GTNode(E input) {
this(input, null, null);
}
public GTNode(E input, GTNode<E> lNode, GTNode<E> rNode) {
data = input;
left = lNode;
right = rNode;
}
}
}
This code does absolutely nothing.
private boolean add(E e, GTNode<E> root) {
if (root == null) {
root = new GTNode<E>(e);
size++;
return true;
}
...
Java passes in the Object Reference to a method. If you change the Reference, that will not
be propagated back to the calling method. If you change what the Reference refers to
that will be propagated back.
eg
// arrays behave the same way so using them to illustrate.
public void callMethods(){
int[] array = new int[1];
array[0] = 0;
doesNotChange(array);
System.out.println(array[0]);// will print 0
doesAChange(array);
System.out.println(array[0]);// will print 1
}
public void doesNotChange(int[] myArray){
myArray = new int[1];
myArray[0] = 1;
}
public void doesAChange(int[] myArray){
myArray[0] = 1;
}
To avoid these sorts of things I recommend always setting method parameters final.
The GTNode class shouldn't be static. Static classes are classes with only static methods, which means they don't have to be instantiated. The prototypical example of this is the java.lang.Math class: You don't need to call something like Math m = new Math(); m.cos(); to get the cosine, you just call Math.cos(). Since you're creating multiple instances of the GTNode class, make it non-static and you should be good.

Categories