Creating a stack with an array, what am I doing wrong? - java

Pretty simple idea, I am just not sure why it won't work. I am getting an error when I call Stack b = new Stack(5); in main.
Here is main
public class Test {
public static void main(String[] args) {
Stack b = new Stack(5);
b.push('a');
b.push('b');
b.push('c');
b.printStack();
}
}
Here is my stack class
public class Stack {
char[] stack;
int items;
public Stack(int size) {
stack = char[size];
items = 0;
}
public void push (char add){
if (items == stack.length) {
System.out.println("Stack is full");
}
else {
stack[items] = add;
}
}
public void printStack() {
if (items == 0)
return;
else {
for (int i = 0; i < items; i++)
System.out.println(i);
}
}
}

One thing is:
public Stack(int size) {
stack = new char[size];
//^^^you missed new
items = 0;
}
Meanwhile
stack[items] = add; //should also increment items

You need to new up your array.
I can see that your push doesn't increment the items count. When you push onto your stack, you should also increment the count.

in your constructor use
stack = new char[size];

You are not using the new keyword when creating your stack array in the constructor.
Furthermore, your push() method does not increment items, and thus will simply constantly overwrite the first element of the stack array.
Finally, your printStack() method will not function as you expect it to. Rather, it will print incremental digits up to the number 5. You will need to change the print statement for it to work.
System.out.println(stack[i]);

Related

Why won't my recursive function recurse through all of the data in the stack?

I am trying to reverse a stack of type int using recursion. I am able to reverse the first entry, but it shows only zeros when I try to print the supposed reversed stack after the recursion takes place. Here is my code:
//Class to reverse a stack using recursion
class ReverseStack
{
//Global Variables
static int[] stack = new int[5];
static int[] tempStack = new int[5];
private static int size;
//Constructor
public ReverseStack()
{
}
//Functions to for the stack
public static boolean isEmpty()
{
return size == 0;
}
//Function to determine if stack is full
public static boolean isFull()
{
return size == stack.length;
}
//Function to determine size of array
int size()
{
return size;
}
//Function to push entries into stack
public static boolean push(int[] stack, int data)
{
if(isFull())
{
return false;
}
else
{
stack[size] = data;
size++;
return true;
}
}
//Function to remove entries from stack
public static int pop()
{
if(isEmpty())
{
return 0;
}
else
{
size--;
return(stack[size + 1]);
}
}
//Function to print the stack
public static void print(int[] stack)
{
//This prints top to bottom
//Top is the last entry
System.out.println("Top to Bottom");
if(isEmpty())
{
System.out.println("The stack is empty ");
}
else
{
for(int cntr = 0; cntr < size; cntr++)
{
System.out.println(stack[cntr] + " ");
}
}
}
//Function to reverse data recursively
public static void reverseData(int data)
{
//Variables
int tempNum;
int cntr = 4;
int cntr2 = 0;
//Note:
/*
To reverse a stack we need to
1. pass in a number
2. Remove the number
3. Repeat until no numbers are left
4 copy stack
5. print
*/
if(data > stack[cntr - 1])
{
tempStack[cntr2] = data;
cntr--;
cntr2++;
data = stack[cntr - 1];
reverseData(data);
}
}
}
I call this reverseStack function in my program's menu system:
//Function to create a menu system
public static void menu()
{
//Variables
int response;
//Message user
System.out.println("Would you like to: "
+ "\n(1) Reverse a stack using recursion "
+ "\n(2) Draw the Sierpinski Triangle "
+ "\n(3) Draw the Dragon Curve "
+ "\n(4) Recurse through a file/directory system"
+ "\n(5) Recurse through my own recursive function"
+ "\n(6) Quit the program ");
//Save user's response
response = Integer.parseInt(myScanner.nextLine());
//Switch statement for menu options
switch (response)
{
case 1:
{
//Create a new instance of ReverseStack class
ReverseStack rs = new ReverseStack();
//Add data into stack before reversing the stack
rs.push(stack, 10);
rs.push(stack, 20);
rs.push(stack, 30);
rs.push(stack, 40);
rs.push(stack, 50);
//Print stack
rs.print(stack);
//Call function to reverse data set
rs.reverseData(stack[4]);
//Print data set
rs.print(rs.tempStack);
//Return to menu
menu();
break;
}
}
}
Do you know what I may be doing wrong?
Size seems to be always 1 above the index of the last element in the stack, so your pop method should probably be
size--;
return stack[size]; // not stack[size+1]
Also your reverseData function is not working because you are resetting cntr and cntr2 each time the function is called. Those must be global variables.
Maybe try something like
int counter = 0;
public void reverseData (int index) {
if (index > counter) {
int temp = data[index];
data[index] = data[counter];
data[counter] = temp;
counter++;
reverseData(--index);
}
You need to know the next index of your tempStack. Right now it is always 0. So you are only updating the first value and rest are 0s
Change your method
//Function to reverse data recursively
public static void reverseData(int data)
{
//Variables
int tempNum;
int cntr = 4;
int cntr2 = 0;
//Note:
/*
To reverse a stack we need to
1. pass in a number
2. Remove the number
3. Repeat until no numbers are left
4 copy stack
5. print
*/
if(data > stack[cntr - 1])
{
tempStack[cntr2] = data;
cntr--;
cntr2++;
data = stack[cntr - 1];
reverseData(data);
}
}
with this
//Function to reverse data recursively
public static void reverseData(int data, int cntr2)
{
//Variables
int tempNum;
int cntr = 4;
//Note:
/*
To reverse a stack we need to
1. pass in a number
2. Remove the number
3. Repeat until no numbers are left
4 copy stack
5. print
*/
if(data > stack[cntr - 1])
{
tempStack[cntr2] = data;
cntr--;
cntr2++;
data = stack[cntr - 1];
reverseData(data, cntr);
}
}
In your main method, call reverseData(stack[4], 0)
Or create cntr2 as class level variable
If it is a temp stack please not define it as static variable. It is not safe and not good coding behavior.
You used two pointers. The cntr points to the last variable, and the cntr2 points to the first variable. Why not compare them?
For example, keep recursing until the cntr2 less than cntr.

How check if the array is full and only add to it if it's not? [duplicate]

I've got array. I've got an isFull method, which checks if the array is full, but I don't know how to use this to check if it's full, then if it's not full add to the array, otherwise disregard the add call.
The array should take 10 elements and then not accept any more. After 10 elements, it should 'be full' and disregard any addSpy calls.
How would you implement this?
public class ConcreteSubject extends AbstractSubject {
public int arySize;
private int i = 0;
private static AbstractSpy[] spies;
public ConcreteSubject(int a) {
arySize = a;
spies = new AbstractSpy[a];
}
#Override
public void addSpy(AbstractSpy spy) {
if (spies.length < 10) {
spies[i] = spy;
System.out.println("spy added at index " + i);
i++;
}
}
public void isFull() {
//1
boolean b = false;
for (int i = 0; i < spies.length; i++) {
if (spies[i] == null) {
b = true;
}
}
if (!b) {
System.out.println("Array is full");
} else {
System.out.println("Array not full");
}
}
public class TestSpies {
public static void main(String[] args) {
ConcreteSubject cs = new ConcreteSubject(10);
AbstractSpy spy = new ConcreteSpy();
AbstractSpy[] spies = new AbstractSpy[10];
cs.addSpy(spy);
cs.addSpy(spy);
cs.addSpy(spy);
cs.isFull();
}
}
spies.length < 10 isn't correct. It should be spies.length > 0 && i < spies.length to make sure that the following assignment spies[i] = spy; is always valid.
void isFull() should be boolean isFull(). Your implementation looks OK, just return b. full is a tricky word because technically an array is always "full". A better adjective would be populated, filled.
Since addSpy isn't filling null gaps but simply adds a spy to the end, isFull could be rewritten to return spies.length == i;.
The simplest way of doing it would be like that:
#Override
public void addSpy(AbstractSpy spy) {
if (!isFull())
{
spies[i] = spy;
System.out.println("spy added at index " + i);
i++;
}
}
To use that, you should change your isFull method to:
public boolean isFull() {
for (int i = 0; i < spies.length; i++) {
if (spies[i] == null) {
return false;
}
}
return true;
}
Keep a track of the number of filled cells of the array using a variable. And before inserting anything into it, check if the filled cells count strictly less than the size of the array (obviously you want to keep track of the array total size as well).

Problem in implementing the methods according to test file

I was able to make the Constructor and capacity methods to works but don;t know why size(),isFull() and isEmpty() fails.I believe its pretty simple but i am just unable to see a minor error and fix it.Hope someone can clarify what i am doing wrong with thorough explaination.Also,my constructor works with the test file and it passes,but just want to know Is my constructor correct as specified by question?
import java.util.Arrays;
import java.util.Iterator;
public class SortedArray<T extends Comparable> implements
java.lang.Iterable<T> {
public SortedArray(int capacity) {
this.array = (T[]) new Comparable[0];
this.capacity = capacity;
this.size = 0;
}
public SortedArray(int capacity, T[] data) {
if(capacity > data.length)
{
this.capacity = capacity;
}
else {
this.capacity = data.length;
}
this.size = data.length;
this.array = (T[]) new Comparable[0];
}
final public int size() {
return this.size
}
final public int capacity() {
return this.capacity;
}
final boolean isEmpty() {
return size == 0;
}
final boolean isFull(){
return size == capacity;
}
#Override
final public Iterator<T> iterator() {
// Do not modify this method.
return Arrays.stream(array).iterator();
}
// Do not modify these data members.
final private T[] array; // Storage for the array's element
private int size; // Current size of the array
final private int capacity; // Maximum size of the array
}
//// Test File:
#Test
public void testConstructor() {
System.out.println("Constructors");
SortedArray array = new SortedArray(20);
assertEquals(array.size(), 0);
assertEquals(array.capacity(), 20);
Integer[] data = {1, 2, 3, 4};
array = new SortedArray(20, data);
assertEquals(array.size(), 4);
assertEquals(array.capacity(), 20);
array = new SortedArray(2, data);
assertEquals(array.size(), 4);
assertEquals(array.capacity(), 4);
}
#Test
public void testSize() {
System.out.println("size");
SortedArray arr = new SortedArray(10);
// Array is initially empty
assertEquals(arr.size(), 0);
// Inserting elements increases size
arr.add(12);
arr.add(13);
arr.add(14);
assertEquals(arr.size(), 3);
// Inserting duplicates increases size
arr.add(12);
arr.add(13);
assertEquals(arr.size(),5);
// Fill up the array
for(int i = 0; i < 5; ++i)
arr.add(i);
assertEquals(arr.size(), 10);
// Size does not change when array is full
arr.add(10);
arr.add(11);
assertEquals(arr.size(), 10);
// Removing elements decreases size
arr.remove(0);
arr.remove(1);
arr.remove(2);
assertEquals(arr.size(), 7);
// but removing elements that don't exist doesn't change anything
arr.remove(100);
assertEquals(arr.size(), 7);
// Removing from the empty array doesn't change size.
SortedArray empty = new SortedArray(10);
empty.remove(10);
assertEquals(empty.size(), 0);
}
#Test
public void testCapacity() {
System.out.println("capacity");
SortedArray array = new SortedArray(20);
assertEquals(array.capacity(), 20);
array = new SortedArray(100);
assertEquals(array.capacity(), 100);
Integer[] data = {1,2,3,4,5,6,7,8,9,0};
array = new SortedArray(20, data);
assertEquals(array.capacity(), 20);
array= new SortedArray(5, data);
assertEquals(array.capacity(), 10);
}
#Test
public void testIsEmpty() {
System.out.println("isEmpty");
SortedArray array = new SortedArray(10);
assertTrue(array.isEmpty());
array.add(10);
assertFalse(array.isEmpty());
array.remove(10);
assertTrue(array.isEmpty());
}
#Test
public void testIsFull() {
System.out.println("isFull");
SortedArray array = new SortedArray(5);
assertFalse(array.isFull());
array.add(10);
array.add(11);
array.add(12);
array.add(13);
array.add(14);
assertTrue(array.isFull());
array.remove(10);
assertFalse(array.isFull());
}
#Test
public void testIterator() {
}
testSize Failed : Expected <0> but was <3>
testCapacity Failed : Expected <5> but was <10>
testConstructor Failed : Expected <0> but was <4>
testisFull Failed : jUnit.framework.AssertionFailedError
testisEmpty Failed : jUnit.framework.AssertionFailedError
You forgot to include your "add(T toAdd)" and "remove(T toRemove)" methods, which when I was going through to make the tests pass, was the source of a vast majority of the fails. (Note: a trace of the fails would help, since your adds and removes need to be pretty complicated to fit the design it seems you intend)
Anyways, on to fixing what I can see.
In your second constructor, you never actually assign the data you take in. You call this.array = (T[]) new Comparable[0]; which creates an empty array of type Comparable. In reality, you need to call this.array = data in order to keep what's been given to you.
Another thing, in your size() method you forgot to place a semicolon after this.size. That tends to prevent things from passing.
Finally, final private T[] array can't have final, or you'll never be able to add or remove elements.
As a bonus, here are the add() and remove() methods I used to fit the requirements and make the tests pass (with comments!!!!):
public void add(T t) {
if (!(size >= capacity)) { //If there's room...
if (size == 0) //If the array is empty...
array[0] = t; //Add to first index
else
array[size] = t; //Add to next available index
size++;
}
}
public void remove(T element) {
if (size <= 0) //If the array is empty...
return; //Stop here
else {
for (int i = 0; i <= this.size(); i++) { //Linear search front-to-back
if (array[i].equals(element)) { //Find first match
array[i] = null; //Delete it
size--;
if (i != size) { //If the match was not at the end of the array...
for (int j = i; j <= (this.size() - 1); j++)
array[j] = array[j + 1]; //Move everything after the match to the left
}
return; //Stop here
}
}
}
}
On a side note, your calls to create SortedArray objects should really be parameterized (Using the <> such as SortedArray<Integer> arr = new SortedArray<Integer>(5, data);).

Performing stack operation to push string in java without collection api

In my java program I want to perform stack operation like push and pop. I also want to push string in stack operation but when I try to push string. I get error mentioned in screenshot. How should I change push method in order to run the program successfully.
code ::
public class DataStack {
private static final int capacity = 3;
String arr[] = new String[capacity];
int top = -1;
public void push(String pushedElement) {
if (top < capacity - 1) {
top++;
arr[top] = pushedElement;
printElements();
} else {
System.out.println("Stack Overflow !");
}
}
public void pop() {
if (top >= 0) {
top--;
System.out.println("Pop operation done !");
} else {
System.out.println("Stack Underflow !");
}
}
public void printElements() {
if (top >= 0) {
System.out.print("Elements in stack : ");
for (int i = 0; i <= top; i++) {
System.out.println(arr[i]);
}
}
}
public static void main(String[] args) {
DataStack stackDemo = new DataStack();
stackDemo.push("china");
stackDemo.push("india");
stackDemo.push("usa");
}
}
Error::
Your push() method and underlying arr variable should be of String type.
String arr[] = new String[capacity];
public void push(String pushedElement) {
...
}
Your array is declared to store only integers . Not to mention, the stackDemo.push method also declared to take in only int arguments.
int arr[] = new int[capacity];
public void push(int pushedElement) {
you should try pushing in integers.
stackDemo.push(1);
stackDemo.push(2);
stackDemo.push(3);

Creating an Array List from scratch

I was wondering if anyone would be able to point me in the correct direction in regards to creating my own array list methods. For instance, the current project I am assigned to does not allow for me to use the methods given to me for free like in the following example.
package com.tutorialspoint;
import java.util.ArrayList;
public class ArrayListDemo {
public static void main(String[] args) {
// create an empty array list with an initial capacity
ArrayList<Integer> arrlist = new ArrayList<Integer>(5);
// use add() method to add elements in the list
arrlist.add(15);
arrlist.add(22);
arrlist.add(30);
arrlist.add(40);
// adding element 25 at third position
arrlist.add(2,25);
// let us print all the elements available in list
for (Integer number : arrlist) {
System.out.println("Number = " + number);
}
}
}
This example shows the add() method. For my project I have to create this method myself and call it from a different file within my package.
I find this as an interesting problem. I am always curious about how things work at the raw level.
If you think about it, an ArrayList is basically just an array that you can expand. So you can either have a really big array (which would take a lot of memory for one ArrayList) or every time you add something, you make a new bigger array and copy the contents and add the new item (which I think the performance is O(N)).
This is my attempt without using any libraries:
public class MyArrayList<T>
{
private T[] asArray;
#SuppressWarnings("unchecked")
public MyArrayList()
{
asArray = (T[]) new Object[0];
}
public void add(T t)
{
#SuppressWarnings("unchecked")
T[] temp = (T[]) new Object[asArray.length + 1];
// copy everything over to the new array
for (int i = 0; i < asArray.length; i++)
{
temp[i] = asArray[i];
}
// add the new element
temp[asArray.length] = t;
asArray = temp;
}
public void remove(int index)
{
if (index < 0 || index >= asArray.length) return;
#SuppressWarnings("unchecked")
T[] temp = (T[]) new Object[asArray.length - 1];
boolean found = false;
// copy everything over to the new element
for (int i = 0; i < asArray.length; i++)
{
// don't copy if the indices are the same
if (i == index)
{
found = true;
continue;
}
temp[i - (found ? 1 : 0)] = asArray[i]; // it's i - 1 after the removed object so then it doesn't leave a gap and it doesn't go over the array's length
}
asArray = temp;
}
public T get(int index)
{
return asArray[index];
}
}
I am quite proud of this code. :) I consider Short_Teeth's code cheating because the class is a subclass and, well, doesn't add anything. I hope I helped.
This is very easy to understand; However, I explained a little bit in comments.
public class MyArrayList<E extends Object> {
private static int initialCapacity = 5;
private static int currentSize;
private Object[] myArrayList = {}, temp = {};
private static int currentIndex = 0;
public static void main(String[] args) {
MyArrayList arrList = new MyArrayList();
arrList.add("123"); //add String
arrList.printAllElements();
arrList.add(new Integer(111)); //add Integer
arrList.printAllElements();
arrList.add(new Float("34.56")); //add Integer
arrList.printAllElements();
arrList.delete("123");
arrList.printAllElements();
arrList.delete(123);
arrList.printAllElements();
arrList.delete(123);
arrList.printAllElements();
}
public MyArrayList() { //creates default sized Array of Objects
myArrayList = new Object[initialCapacity]; //generic expression
/* everytime I cross my capacity,
I make double size of Object Array, copy all the elements from past myObject Array Object
*/
}
public MyArrayList(int size) { //creates custom sized Array of Objects
myArrayList = new Object[size];
}
public void add(Object anyObj) {
//add element directy
myArrayList[currentIndex] = anyObj;
currentSize = myArrayList.length;
currentIndex++;
if (currentIndex == currentSize) {
createDoubleSizedObjectArray(currentSize);
}
}
//print all elements
public void printAllElements() {
System.out.println("Displaying list : ");
for (int i = 0; i < currentIndex; i++) {
System.out.println(myArrayList[i].toString());
}
}
private void createDoubleSizedObjectArray(int currentSize) {
temp = myArrayList.clone();
myArrayList = new MyArrayList[2 * currentSize]; //myObject pointer big size data structure
// myObject = temp.clone(); //probably I can do this here as well. Need to check this
System.arraycopy(temp, 0, myArrayList, 0, currentSize);
}
void delete(Object object) {
//if already empty
if (currentIndex == 0) {
System.out.println("Already empty!");
return;
}
//you don't need to delete anything. I can simply override the storage
currentIndex--;
}
}
import java.util.ArrayList;
public class MyArrayList<E> extends ArrayList<E>{
private static final long serialVersionUID = -5164702379587769464L;
public void newMethod(){
// No implementation
}
}
This is a class which extends from ArrayList and a method called newMethod() was added to this class.
Below we are calling this newly created method in your case you must implement the add to this newly created method.
public class Hello {
public static void main(String args[]) {
MyArrayList<Integer> myList = new MyArrayList<Integer>();
// It has the ArrayList add() method as this new class extends from ArrayList (all the ArrayList methods are included)
myList.add(2);
// The newly created method in your case you need to implement the add yourself
myList.newMethod();
}
}
This could also be a good link for what you need.
http://www.java2novice.com/java-interview-programs/arraylist-implementation/
I also recomend that you try to implement and solve your problems first and then ask questions about a specific problem, and only after you done a good research about what may be causing this problem (There are lots of resources out there). If you done some research before you asked this question, I'm pretty sure that you would have been able to solve everything on your own.
Hope you find this information useful. Good luck.

Categories

Resources