I have just started Java.I have some C++ experience.I want to implement a stack class.Here is my class:
public class stack {
private static int MAX;
stack(int a)
{
MAX = a;//input max size of stack
}
stack()
{
MAX = 1000;//default max size stack is 1000
}
private int[] my_stack = new int[MAX];
private int top = 0;
public void push(int x)
{
if (this.top > MAX)System.out.println("OVERFLOW");
else my_stack[this.top++] = x;//ERROR LINE
}
public void pop()
{
if (this.top == 0)System.out.println("TOO LOW");
else this.top--;
}
public int top()
{
return my_stack[this.top - 1];
}
}
The error says:
Index 0 out of bounds for length 0
at stack.push(stack.java:17)
at MainClass.main(MainClass.java:7)
Can anyone explain me the problem?
Here some minimal changes, explained with comments
public class stack {
private int max; //Removed static here and changed to lowercase, this is an instance field
stack(int a)
{
max = a; //input max size of stack
my_stack = new int[max]; //Here the value of max is initialized an you can use it
}
stack()
{
this(1000); //Call other constructor, just to avoid duplicate code
}
private int[] my_stack; //You can't initialize the array there, since you don't know the size yet
private int top = 0;
public void push(int x)
{
if (this.top >= max)System.out.println("OVERFLOW"); //You must check with >=, not just > since the maximum index is max-1
else my_stack[this.top++] = x;//ERROR LINE
}
public void pop()
{
if (this.top == 0)System.out.println("TOO LOW");
else this.top--;
}
public int top()
{
return my_stack[this.top - 1];
}
}
Related
private MyStack stack1 = new MyStack();
private MyStack stack2 = new MyStack();
public int dequeue() {
int x = 0;
while(!stack1.isEmpty()) {
stack2.push(stack1.pop());
}
return x;
}
The program is to move items from stack 1 to 2. The problem is that it throws a StackEmptyException when I push from stack 1 to 2. I tried to push normal integers to both stacks and it seemed fine.
public class MyStack {
static final int MAX = 100;
private int[] array = new int[MAX];
private int top;
public MyStack(){
top = -1;
}
boolean isEmpty() {
return (top < 0);
}
public void setArraySize(int x) {
array = new int[x];
}
public int peek(){ // displays the number on top of stack
return array[top];
}
public void push(int x) { // puts a number on top of stack
if(top>=array.length-1) {
System.out.println("StackFullException");
}
array[++top] = x;
}
public int pop() { // removes the number that is on top of stack
if(top<array.length) {
System.out.println("StackEmptyException");
}
int x = array[top--];
return x;
}
}
This is my stack declaration that is based from an array.
public int pop() { // removes the number that is on top of stack
if(top<0) {
System.out.println("StackEmptyException");
}
int x = array[top--];
return x;
}
I mistakenly set my if statement to throw a StackEmptyExeception if top < the array.
I've created stack and queue arrays which hold integers and have a max capacity of ten. I added the values 1-11 and then will remove and print each value until empty. The queue is not only printing 11 values, but also printing 1 instead of 11 for the first value. The stack however is only printing and removing the 10 values but is giving me an IndexOutBoundsException that is not being caught. Any idea why?
Output:
run:
Print queue:
11 2 3 4 5 6 7 8 9 10 11
Print stack:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
at lab4.Stack.pop(Stack.java:44)
at lab4.Lab4.main(Lab4.java:54)
10 9 8 7 6 5 4 3 2 1
BUILD FAILED (total time: 0 seconds)
Main:
Queue queue = new Queue(10);
Stack stack = new Stack(10);
queue.insert(1);
queue.insert(2);
queue.insert(3);
queue.insert(4);
queue.insert(5);
queue.insert(6);
queue.insert(7);
queue.insert(8);
queue.insert(9);
queue.insert(10);
queue.insert(11);
stack.push(1);
stack.push(2);
stack.push(3);
stack.push(4);
stack.push(5);
stack.push(6);
stack.push(7);
stack.push(8);
stack.push(9);
stack.push(10);
stack.push(11);
System.out.println("Print queue: ");
while (!queue.isEmpty()) {
long n = queue.remove();
System.out.print(n + " ");
}
System.out.println("");
System.out.println("Print stack: ");
while (!stack.isEmpty()) {
Object value = stack.pop();
System.out.print(value + " ");
}
Stack.java
public class Stack {
private int[] stackArray; // Stack array of objects
private int maxSize = 10; // Max size of the stack
private int top; // top integer of stack
public Stack(int maxSize) {
stackArray = new int[maxSize];
top = -1;
}
public boolean isEmpty() {
return (top == maxSize); // true if stack is empty
}
public boolean isFull() {
return (top == maxSize - 1); // true if full
}
public int size() {
return (top + 1); // Return the # of items
}
public void push(int item) // put element into array
{
if (!isFull()) {
top++;
stackArray[top] = item;
}
}
public Object pop() {
if (!isEmpty()) {
top--;
return stackArray[top + 1];
} else
throw new IllegalStateException("Stack empty");
}
public Object peek() {
return stackArray[top];
}
public String toString() {
return "Size: " + maxSize + " Capcaity: " + top; // complete: show the size and capacity
}
}
Queue.java
public class Queue {
private int maxSize = 10;
private int[] queueArray;
private int front;
private int rear;
private int nItems;
// Constructor
public Queue(int s) {
queueArray = new int[maxSize];
front = 0;
rear = -1;
nItems = 0;
}
// Insert item at rear of queue
public void insert(int j) {
if (rear == maxSize - 1) { // Deal with wraparound
rear = -1;
}
queueArray[++rear] = j;
nItems++;
}
public int remove() {
int temp = queueArray[front++];
if (front == maxSize) {
front = 0;
}
nItems--;
return temp;
}
public int peekFront() {
return queueArray[front];
}
public int peekRear() {
return queueArray[front];
}
public boolean isEmpty() {
return (nItems == 0);
}
public boolean isFull() {
return (nItems == maxSize);
}
public int size() {
return nItems;
}
}
These are pretty simple fixes! For the queue, you need to set your maxSize to 11. This will allow you to print each number in the queue correctly without printing the 11 in front. Long story short, given you have 11 total elements in your queue, a max queue size of 11 is necessary.
public class Queue {
private int maxSize = 11;
private int[] queueArray;
private int front;
private int rear;
private int nItems;
}
Now, in terms of your stack, this was also a pretty simple fix. As of right now, your code is returning top == maxSize (or 10) when the stack is empty. This is causing an issue with the pop function. However, when the stack is empty, top should equal -1. So make sure to set top == -1 in the isEmpty() function. You should also change int maxSize = 10 to int maxSize= 11 and make the necessary change in the pop() function as well as this is where the error is occurring. Finally, make sure to change the value in your stack initialization from 10 to 11. I've changed your code and it should now work properly! Enjoy!
public class Stack {
private int[] stackArray; // Stack array of objects
private int maxSize = 11; // Max size of the stack
private int top; // top integer of stack
public Stack(int maxSize) {
stackArray = new int[maxSize];
top = -1;
}
public boolean isEmpty() {
return (top == -1); // true if stack is empty
}
public boolean isFull() {
return (top == maxSize); // true if full
}
public int size() {
return (top-1); // Return the # of items
}
public void push(int item) // put element into array
{
if (!isFull()) {
top++;
stackArray[top] = item;
}
}
public Object pop() {
if (!isEmpty()) {
return stackArray[top--];
} else
throw new IllegalStateException("Stack empty");
}
public Object peek() {
return stackArray[top+1];
}
public String toString() {
return "Size: " + maxSize + " Capcaity: " + top; // complete: show the size and capacity
}
I need to implement a stack array using a dynamic array which I had to create myself.
Here's my dynamic array:
import java.util.Arrays;
public class Array {
public int[] dynArray;
int counter = 0;
public void create(int n) {
dynArray = new int[n];
}
public void doubleSize() {
int currentSize = dynArray.length;
int newSize = currentSize*2;
dynArray = Arrays.copyOf(dynArray, newSize);
}
private void halfSize() {
int currentSize = dynArray.length;
int newSize = currentSize/2;
dynArray = Arrays.copyOf(dynArray, newSize);
}
public void add(int x) {
dynArray[counter] = x;
counter++;
float ratio = (float) counter / (float) dynArray.length;
if (ratio == 1) {
doubleSize();
}
}
public int rem() {
int last = dynArray[counter-1];
dynArray[counter-1] = 0;
counter--;
float ratio = (float) counter / (float) dynArray.length;
if (ratio <= 0.25) {
halfSize();
}
return last;
}
public int get(int i) {
if(!(check(i))) {
//System.out.print("Cannot be added");
return i;
}
else return dynArray[i];
}
public void put(int x, int y) {
float ratio = (float) counter / (float) dynArray.length;
if (ratio ==1) {
doubleSize();
}
if(!check(y)) {
System.out.println("No such index, nothing added to "+y);
} else {
dynArray[y] = x;
}
}
public int len() {
return dynArray.length;
}
public boolean check(int index) {
if(index <0 || index >=dynArray.length) {
return false;
} else {
return true;
}
}
public static void main(String[] args) {
Array dm = new Array();
dm.create(5);
System.out.println("Current array length "+dm.len());
dm.add(5);
dm.add(4);
dm.add(3);
dm.add(1);
dm.add(2);
System.out.println("Current array length "+dm.len());
dm.rem();
dm.rem();
System.out.println("Current array length "+dm.len());
dm.rem();
System.out.println("Current array length "+dm.len());
dm.rem();
System.out.println("Current array length "+dm.len());
}
}
Here's my stack code:
public class Stack {
private static Array a;
public void create() {
a = new Array();
}
void push(int x) {
a.add(x);
}
int pop() {
return a.rem();
}
boolean isEmpty() {
return a.len() == 0;
}
public static void main(String[] args) {
Stack stack = new Stack();
stack.create();
stack.push(1);
/*int k = 1;
stack.push(2*k);
stack.push(2*k+1);
stack.push(2*k+2);
for (int i = 0; i<40; i++) {
System.out.println(stack.pop());
}*/
}
}
When I write stack.push(1) in Stack.java main, it gives me a NullPointerException on the line where it says a.add(x). I don't understand why this exception occurs.
Your create method in your Stack creates a new Array instance, but doesn't call the Array's create method. Therefore dynArray remains null, and you get the NullPointerException when it's accessed (in dynArray[counter] = x;).
You should probably call create in the constructor of Array (or eliminate the create method and move its code to the constructor).
I need to modify a class to create a dynamic array stack.
My code at this point looks something like this:
public class DynamicArrayStack<E> implements Stack<E> {
private E[] elems; //used to store the elements
public static final int defaultIncrement = 25;
private final int increment;
private int top;
#SuppressWarnings( "unchecked" )
public DynamicArrayStack( int increment ) {
this.increment = increment;
elems = (E[]) new Object[ increment ];
top = 0;
}
/**
* Constructor with no parameter that will initialize
* the stack to have an array whose size is the value
* of increment and memorise that value as the value
* of increment.
*/
public void ArraySize() { }
public boolean isEmpty() {
return top == 0;
}
public E peek() {
return elems[ top-1 ];
}
public E pop() {
// save the top element
E saved = elems[ --top ];
// scrub the memory, then decrements top
elems[ top ] = null;
return saved;
}
public void push( E elem ) {
// stores the element at position top, then increments top
elems[ top++ ] = elem;
}
public String toString() {
StringBuffer b;
b = new StringBuffer( "DynamicArrayStack: {" );
for ( int i=top-1; i>=0; i-- ) {
if ( i!=top-1 ) {
b.append( "," );
}
b.append( elems[ i ] );
}
b.append( "}" );
return b.toString();
}
}
How do I edit the first constructor to set increment as the initial size of the stack and that same value to be used when increasing or decreasing the size of the array. My method for doing this seems way too simple. Parameter must be > 0 and a fixed number of cells are added or removed when the size of the array changes.
The second constructor should set the stack to have an array whose size is the value of increment. I keep getting errors here because I can't figure out how to do that because I thought that was already set in the first constructor. Also the size of the array as the value of increment.
Also how do I make this class capable of changing the capacity of the stack and into which method should I place that code?
Here is the simple java code to implement it:
1)Stack based:
public class DynamicArrayStack {
public static void main(String[] args) {
DynamicStack dstack=new DynamicStack(2);
System.out.println("--Pushing--");
dstack.push(1);
dstack.push(2);
dstack.display();
dstack.push(3);
dstack.push(2);
dstack.push(5);
dstack.display();
System.out.println("--Popping--");
dstack.pop();
dstack.pop();
dstack.pop();
dstack.display();
}
}
class DynamicStack {
private int top;
private int capacity;
private int[] array;
public DynamicStack(int cap) {
capacity = cap;
array = new int[capacity];
top = -1;
}
public void push(int data) {
if (isFull()){
expandArray(); //if array is full then increase its capacity
}
array[++top] = data; //insert the data
}
public void expandArray() {
int curr_size = top + 1;
int[] new_array = new int[curr_size * 2];
for(int i=0;i<curr_size;i++){
new_array[i] = array[i];
}
array = new_array; //refer to the new array
capacity = new_array.length;
}
public boolean isFull() {
if (capacity == top+1)
return true;
else
return false;
}
public int pop() {
if (isEmpty()) {
System.out.println("Stack is empty");
return -1;
} else {
reduceSize(); //function to check if size can be reduced
return array[top--];
}
}
public void reduceSize() {
int curr_length = top+1;
if (curr_length < capacity / 2) {
int[] new_array = new int[capacity / 2];
System.arraycopy(array, 0, new_array, 0, new_array.length);
array = new_array;
capacity = new_array.length;
}
}
public boolean isEmpty() {
if (top == -1)
return true;
else
return false;
}
public void display() {
for (int i = 0; i <= top; i++) {
System.out.print(array[i] + "=>");
}
System.out.println();
System.out.println("ARRAY SIZE:" + array.length);
}
}
OUTPUT:
--Pushing--
1=>2=>
ARRAY SIZE:2
1=>2=>3=>2=>5=>
ARRAY SIZE:8
--Popping--
1=>2=>
ARRAY SIZE:4
2)Link List based:
public class LinkListStack {
public static void main(String[] args) {
StackList stack = new StackList();
System.out.println("--Pushing--");
stack.push(1);
stack.push(2);
stack.push(3);
stack.push(4);
stack.push(5);
stack.push(6);
stack.display();
System.out.println("--Popping--");
stack.pop();
stack.pop();
stack.display();
}
}
class Node {
private int data;
private Node next;
public Node(int d) {
data = d;
next = null;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
class StackList {
private Node top;
private int length;
public StackList() {
length = 0;
top = null;
}
public void push(int data) {
Node temp = new Node(data);
if (top == null) {
top = temp;
} else {
temp.setNext(top);
top = temp;
}
length++;
}
public int pop() {
Node temp=top;
int data = top.getData();
top = top.getNext();
temp=null;
length--;
return data;
}
public void display() {
Node temp = top;
if (isEmpty()) {
System.out.println("Stack is empty");
} else {
while (temp != null) {
System.out.print(temp.getData() + "=>");
temp = temp.getNext();
}
}
System.out.println();
}
public boolean isEmpty() {
return (top == null);
}
}
OUTPUT:
--Pushing--
6=>5=>4=>3=>2=>1=>
--Popping--
4=>3=>2=>1=>
Default constructor
Your default constructor could simply call your other constructor with a default increment value. For example:
public DynamicArrayStack() {
this(defaultIncrement);
}
Expanding the array
The correct place to expand the array is within the push method. When attempting to add a new element you can check if the array is large enough, and if not create a new larger array. For example you could do the following:
#Override
public E push(final E elem) {
// Check if we need to expand the array
if (elems.length - 1 == top) {
#SuppressWarnings("unchecked")
final E[] newElems = (E[]) new Object[elems.length + increment];
System.arraycopy(elems, 0, newElems, 0, elems.length);
elems = newElems;
}
// stores the element at position top, then increments top
elems[top++] = elem;
return elem;
}
If you want to shrink the array the sensible place to do this would be in the pop() method. You might want to consider only reducing the length when (top + (increment*2))<elems.length to avoid repeatedly copying arrays when you're on the boundary.
My issue is more semantic than functional, As the code does seem to implement the deQueue and enQueue functions correctly.
The reheapDown and reheapUp functions are being used incorrectly, And i believe the issue lies in my heap function
package priqueue;
public class Hosheap{
private Patient[] elements;
private int numElements;
public Hosheap(int maxSize)
{
elements= new Patient[maxSize];
numElements=maxSize;
}
public void ReheapDown(int root,int bottom)
{
int maxChild;
int rightChild;
int leftChild;
leftChild=root*2+1;
rightChild=root*2+2;
if (leftChild<=bottom)
{
if(leftChild==bottom)
maxChild=leftChild;
else
{
if(elements[leftChild].getPriority() <= elements[rightChild].getPriority())
maxChild=rightChild;
else
maxChild=leftChild;
}
if(elements[root].getPriority()<elements[maxChild].getPriority())
{
Swap(root,maxChild);
ReheapDown(maxChild,bottom);
}
}
}
public void ReheapUp(int root,int bottom)
{
int parent;
if(bottom>root)
{
parent=(bottom-1)/2;
if(elements[parent].getPriority()<elements[bottom].getPriority())
{
Swap(parent,bottom);
ReheapUp(root,parent);
}
}
}
public void Swap(int Pos1, int Pos2)
{
Patient temp;
temp = elements[Pos1];
elements[Pos1]=elements[Pos2];
elements[Pos2]=temp;
}
public Patient getElement(int e)
{
return elements[e];
}
public void setElement(Patient p, int n)
{
elements[n]=p;
}
}
The idea is to rearrange a simple priority queue system so when a patient object is removed, ReheapUp or down correctly rearranges the queue, Which the code does not accomplish. Should i also include the priority queue code, Or is this already too lengthy?
I am using NetBeans IDE 6.0.1, If that helps.
Depending on your usage requirements, the answer relating to TreeSets will most probably do what you want.
However if you really need a queue, as opposed to a sorted collection, then the inbuilt PriorityQueue may be of use.
Not exactly answering your question, but with Java you may want to look into the built-in Collection classes. You can get priority queue behavior but using a TreeSet (a type of ordered-set) and implementing a custom Comparator for Patient instances. Depending what you're trying to achieve, this may be preferable. It would look something like this:
In Patient.java ...
class Patient implements Comparator {
...
public int compareTo(Patient other) {
return getPriority() > other.getPriority() ? 1 : 0;
}
Then in the place you want to use the queue
Set<Patient> queue = new TreeSet<Patient>();
queue.add(p1);
queue.add(p2);
//traverse in order of priority
for(Patient p : queue) {
doStuff();
}
Here is a simple implementation of a PriorityHeap. I coded it up pretty quick so it may have some flaws but I have implemented the pushUp() and pushDown() logic.
import java.util.Random;
public class Heap {
private Double[] data;
private int lastItem;
public Heap(int initialSize) {
// to simplify child/parent math leave the first index empty
// and use a lastItem that gives us the size
data = new Double[initialSize];
lastItem = 0;
}
public void insert(Double d) {
// double size if needed
// should have a matching shrink but this is example code
if (lastItem + 1 >= data.length) {
Double[] doubled = new Double[data.length * 2];
System.arraycopy(data, 0, doubled, 0, data.length);
data = doubled;
}
data[lastItem + 1] = d;
lastItem++;
pushUp(lastItem);
}
public void pushDown(int index) {
if (lastItem > 1) {
int leftChildIndex = index * 2;
int rightChildIndex = leftChildIndex + 1;
// assume that neither child will dominate (in priority)
// the item at index
int indexToPromote = index;
// there may not be a left child
if (leftChildIndex <= lastItem) {
Double leftChild = data[leftChildIndex];
Double tmp = data[index];
if (tmp.compareTo(leftChild) < 0) {
indexToPromote = leftChildIndex;
}
// there might not be a right child
if (rightChildIndex <= lastItem) {
Double rightChild = data[rightChildIndex];
tmp = data[indexToPromote];
if (tmp.compareTo(rightChild) < 0) {
indexToPromote = rightChildIndex;
}
}
}
// did either child dominate the item at index
// if so swap and push down again
if (indexToPromote != index) {
swap(index, indexToPromote);
pushDown(indexToPromote);
}
}
}
public void pushUp(int index) {
if (index > 1) {
// equivalent to floor((double)index/2.0d);
// if item at index is greater than its parent
// push the item up to until if finds a home
int parentIndex = index >>> 1;
Double parent = data[parentIndex];
Double item = data[index];
if (item.compareTo(parent) > 0) {
swap(parentIndex, index);
pushUp(parentIndex);
}
}
}
public Double removeTop() {
// assume size is zero then examine other cases
Double top = null;
if (lastItem > 1) {
// save the top item and take the bottom item and place it
// at the top the push the new top item down until it
// finds a home
top = data[1];
Double bottom = data[lastItem];
lastItem--;
data[1] = bottom;
pushDown(1);
} else if (lastItem == 1) {
top = data[1];
lastItem--;
}
return top;
}
public int size() {
return lastItem;
}
private void swap(int index1, int index2) {
Double temp = data[index1];
data[index1] = data[index2];
data[index2] = temp;
}
public static void main(String[] args) {
Heap heap = new Heap(4);
Random r = new Random();
for (int i = 0; i < 100000; i++) {
Double d = Double.valueOf(r.nextDouble() * 100.0d);
heap.insert(d);
}
double max = Double.MAX_VALUE;
while (heap.size() > 0) {
Double top = heap.removeTop();
if (top.doubleValue() > max) {
System.out.println("bad ordering...");
}
max = top.doubleValue();
System.out.println(max);
}
System.out.println("done...");
}
}