I'm quite new to java. So I've got some code that is supposed to add files to a stack and compare the stack contents with an existing reference. Here's the class that should create the stack:
public class ArrayStack<T> implements ArrayStackADT<T> {
private T[] stack;
private int top;
// constructor, passes default capacity
public ArrayStack() {
top = -1;
stack = (T[]) new Object[14];
}
// constructor, initializes capacity to stack and top
public ArrayStack(int initialCapacity) {
top = -1;
stack = (T[])new Object[initialCapacity];
}
}
and here is the code that calls the stack:
public static void main(String[] args){
StartSearch path = new StartSearch(args[0]);
int distance = Integer.parseInt(args[1]);
ArrayStack stack = new ArrayStack(); // creates empty stack
MapCell cell = path.targetMap.getStart(); // gets starting cell
stack.push(cell); // pushes starting cell to stack
}
Not sure if I showed enough code, so please let me know if I didn't. I had some push and pop methods to insert and remove stack items, and for each push/pop they'd print "push" + the value:
if (dataItem instanceof MapCell) {
sequence += "push" + ((MapCell)dataItem).getIdentifier();
}
else {
sequence += "push" + dataItem.toString();
}
For some reason though, when I go to print sequence later, it outputs this:
nullpush0push2push3
Instead of what I need it to output:
push0push2push3
Do empty stacks automatically have a null value or something? how do I get rid of the null value at the beginning?
It hasn’t got anything to do with your stack class. It’s how you initialize your String variable. Or perhaps forgot to initialize it? To demonstrate:
String sequence = null;
sequence += "push1";
System.out.println(sequence);
Output is:
nullpush1
Instead initialize sequence to the empty string:
String sequence = "";
push1
Or use a StringBuffer or StringBuilder:
StringBuilder sequence = new StringBuilder();
sequence.append("push1");
System.out.println(sequence);
Output is identical:
push1
Related
I am having issues with my code regarding exception in thread main. This is the error that is popping up
Exception in thread "main" java.lang.IllegalStateException: Attempt to create a stack whose capacity exceeds allowed maximum of 10000
at ResizeableArrayStack.checkCapacity(ResizeableArrayStack.java:74)
at ResizeableArrayStack.ensureCapacity(ResizeableArrayStack.java:82)
at ResizeableArrayStack.push(ResizeableArrayStack.java:28)
at ResizeableArrayStack.evaluatePostfix(ResizeableArrayStack.java:98)
at ResizeableArrayStack.main(ResizeableArrayStack.java:157)
This is my code
import java.util.*;
public class ResizeableArrayStack<T> implements StackInterface<T>
{
private T[] stack;
private int topIndex;
private boolean integrityOK = false;
private static final int DEFAULT_CAPACITY = 50;
private static final int MAX_CAPACITY = 100000;
public ResizeableArrayStack()
{
this(DEFAULT_CAPACITY);
}
public ResizeableArrayStack(int initialCapacity)
{
integrityOK = false;
checkCapacity(initialCapacity);
// The cast is safe because the new array contains null entries
#SuppressWarnings("unchecked")
T[] tempStack = (T[])new Object[initialCapacity];
stack = tempStack;
topIndex = -1;
integrityOK = true;
}
public void push(T newEntry) {
checkIntegrity();
ensureCapacity();
stack[topIndex + 1] = newEntry;
topIndex++;
}
private void checkCapacity(int capacity) {
if (capacity > MAX_CAPACITY) {
throw new IllegalStateException("Attempt to create a stack whose capacity exceeds allowed
maximum of " + MAX_CAPACITY);
}
} // end checkCapacity
private void ensureCapacity() {
if (topIndex >= stack.length - 1) {
// If array is full, double its size
int newLength = 2 * stack.length;
checkCapacity(newLength);
stack = Arrays.copyOf(stack, newLength);
}
} //end ensureCapacity
public static void main(String[] args) {
String input = "ab*ca-/de*+";
ResizeableArrayStack<String> astack = new ResizeableArrayStack<>(input.length());
int evaluation = astack.evaluatePostfix(input);
System.out.println("Evaluating Postfix Expressions");
System.out.println("The evaluation of the postfix expression is " + evaluation);
}
}
I'm pretty sure the issue is with how the capacity values are set and compared but I can't figure out why I am getting this error. I think the issues are within the constructors that involve capacity and main method. Please ignore the evaluatePostfix method in the main as the errors all say they come from the constructors and main. I can put the evaluatePostfix up if you think the problem is within it. I also deleted the methods that weren't brought up in the problem.
The code you posted is not a MCVE. It doesn't compile because it is missing methods including checkIntegrity and evaluatePostfix. Even after I work around the missing methods, the code you posted does not cause IllegalStateException to be thrown. At a guess, after looking through the code that you did post, as well as the stack trace, the culprit appears to be method ensureCapacity which contains the following line:
int newLength = 2 * stack.length;
The value assigned to newLength may be greater than MAX_CAPACITY.
After you assign a value to newLength, you call method checkCapacity which explicitly throws a IllegalStateException.
private void checkCapacity(int capacity) {
if (capacity > MAX_CAPACITY) {
throw new IllegalStateException("Attempt to create a stack whose capacity exceeds allowed maximum of " + MAX_CAPACITY);
}
} // end checkCapacity
But as I wrote earlier, in the code that you posted capacity is never greater than MAX_CAPACITY and hence the code in your question never throws IllegalStateException.
I recommend that you run your code through a debugger. If you are using an IDE, then it should give you the option of running your code in "debug" mode. If you don't know how to use the debugger of the IDE then you should learn because knowing how to debug code is an essential skill for a programmer and a debugger helps a lot when it comes to debugging your code.
I was attempting a question on leetcode and not sure about this anomalous behaviour. I am providing the logic part of the question. Please let me know if any discrepancy is found.
Question: Design a stack that supports push, pop, top, and retrieving
the minimum element in constant time.
push(x) -- Push element x onto stack.
pop() -- Removes the element on top of the stack.
top() -- Get the top element.
getMin() -- Retrieve the minimum element in the stack.
Link to leetcode question
Approach: Using 2 stacks, values (with original values in their order) and min (with values sorted in ascending order)
class MinStack {
Stack<Integer> min;
Stack<Integer> values;
/** initialize your data structure here. */
public MinStack() {
min = new Stack<>();
values = new Stack<>();
}
public void push(int x) {
if(values.isEmpty()){
values.push(x);
min.push(x);
}
else{
values.push(x);
if(min.peek()<x){
List<Integer> list = new ArrayList<>();
while(!min.isEmpty() && min.peek()<x)
list.add(min.pop());
min.push(x);
for(int i=list.size()-1;i>=0;i--)
min.push(list.get(i));
}
else
min.push(x);
}
System.out.println("min after push-->"+min);
System.out.println("values after push -->"+values);
}
public void pop() {
if(values.peek()==min.peek()){
min.pop();
}
else{
List<Integer> list = new ArrayList<>();
while(!min.isEmpty() && min.peek()!=values.peek()){
list.add(min.pop());
}
if(!min.isEmpty()){
min.pop();
}
for(int i=list.size()-1;i>=0;i--)
min.push(list.get(i));
}
values.pop();
System.out.println("min after pop -->"+min);
System.out.println("values after pop-->"+values);
}
public int top() {
System.out.println("min on top -->"+min);
System.out.println("values on top-->"+values);
return values.peek();
}
public int getMin() {
System.out.println("min for getMin-->"+min);
System.out.println("values for get min-->"+values);
return min.peek();
}
}
/**
* Your MinStack object will be instantiated and called as such:
* MinStack obj = new MinStack();
* obj.push(x);
* obj.pop();
* int param_3 = obj.top();
* int param_4 = obj.getMin();
*/
The wrapper classes like Integer, Long should use equals rather than ==
Use equals here if(values.peek()==min.peek()){
Change it to if(values.peek().equals(min.peek())){
Also min.peek()!=values.peek() to !min.peek().equals(values.peek())
The last thing is you remove the System.out.println lines
One more suggestion would be to not use entire stack for sorted values and recreate it everytime a pop is done on the actual stack.
Rather you should maintain a single min variable and update it if the pop has removed the min item. You can find minimum value using min() method from stream()
You can have a look at the following too
Java: Integer equals vs. ==
How to properly compare two Integers in Java?
I am a beginner in Java looking for some help to finish my assignment. Here you have the assignment text :
A Stack of integers is an abstract data type that allows the following operations:
1) memorize integers (input function)
2) print the memorized numbers in the insertion order (print method)
3) reverse the insertion order of the numbers (reverse method)
4) concatenate two stacks (concatenate method)
5) copy the content of the stack to an array (toarray)
Write a java class to implement the abstract data type of integers. The program should work with the main file.
The first thing i did was create a class that contains the methods such as: print, input, reverse, concatenate, copy, etc to store the integers in an array, print them using the print method, reverse the insertion order. No problems here.
My problem comes when i want to concatenate two arrays of integers (input from the main) using a method in the class. Instead, the program outputs some numbers + the "java.lang.NullPointerException" error which i think i understand reason for.
Here you can see the stack class:
import java.util.Arrays;
public class Repo {
private static int SIZE;
private int [] Repo ;
private int [] Repo2;
private int top;
Repo () {
Repo = new int [SIZE];
}
Repo (int l) {
Repo = new int [l];
}
public void input (int in) {
Repo[top] = in;
top++;
}
public void stampa () { //print
for(top = 0; top < Repo.length; top++ ) {
if(Repo[top]!=0) {
System.out.print(Repo[top] + " ");
}
}
System.out.println();
}
public void gira() { //Invert
for(top=0; top < Repo.length/2; top++) {
int reverse = Repo[top];
Repo[top] = Repo[Repo.length -top -1];
Repo[Repo.length -top -1] = reverse;
}
}
public void appendi(Repo s) { //Append
int aLen = Repo.length;
int bLen = Repo2.length;
int[] result = new int[aLen + bLen];
System.arraycopy(Repo, 0, result, 0, aLen);
System.arraycopy(Repo2, 0, result, aLen, bLen);
}
public void toarray () {
int [] Repo2 = Repo.clone();
}
}
Here you have the main:
public class TestRepo {
// gioca con i repositori di interi
public static void main(String[] args) {
// il risultato deve essere:
//
// 42 43 44 45
// 1 2 3 45 44 43 42
Repo r = new Repo(10);
// r potra' contenere un massimo di 10 elementi
Repo s = new Repo(20);
r.input(42);
r.input(43);
r.input(44);
r.input(45);
r.stampa();
s.input (1);
s.input (2);
s.input (3);
s.gira();
r.appendi(s);
r.gira();
r.stampa();
}
}
As you can see in the main, the numbers were entered using two different references r.input() & s.input().
In order to get the desired output i used the clone method to create a copy of the first array, merge it with a second one and then print it.
The output should be:
42 43 44 45
1 2 3 45 44 43 42
The output i get is:
42 43 44 45
Exception in thread "main" java.lang.NullPointerException
at Repo.appendi(Repo.java:46)
at TestRepo.main(TestRepo.java:32)
I think the cause of the error is that i am not indicating the right reference in the "append" method, but i am not sure. There might be other errors i may not be aware of in my code.
Any help will be appreciated
Thank you very much
As #WJS pointed out, you never initialised Repo2 and there for it's value is null.
therefore: int bLen = Repo2.length; throws an NullPointerException.
I think what you want to do is bLen = s.length as you probably want to size of this Repo plus the size of the repo you want to append, which is s, not Repo2.
This is only regarding your error.
I think your whole implementation is somewhat off.
I would advice you to do some reading on what exactly stacks are, just google it.
Now you work with arrays of integers, but I think you should use Stack instead.
Why would you otherwise have a function called toArray, when your stack implemenation is already an array? Doesn't make sense. I could be wrong tough...
And for your print function I do not see why 0 should not be printed.
Nice job on the inverse though
When performing your changes, you should work only with your stack implementation and nothing else. Here are some pointers.
Repo should only have one array which acts as a stack.
Repo should have a method that prints itself and nothing else.
Repo should be able to reverse itself. That can be done in place, but if you use another array it shouldn't be visible outside of your class. If I were going to do this I would return a reversed version of the stack, rather than mutate one.
The append method should take to stacks. It should create an instance of the stack, populate that instance from the two passed stacks, and return it as a new instance of stack.
A toArray method simply returns a copy of the array backing your stack. Don't just return the array object because mutating that array would also mutate the stack.
The above is how I might approach this. If I said anything that was in conflict with what your instructor wanted or expected, then your instructor's word certainly takes precedence.
Here is an example of how I would handle the append operation. It works as follows:
returns a new stack with the supplied stack appended to the calling stack.
updates the index of the returned stack to point to the next slot.
For an existing Stack one and Stack two to append two to one would be called like this.
Stack appended = one.append(two);
Here is how it might be implemented (has not been thoroughly tested).
data is the internal array that backs the stack
index is the internal pointer that keeps track of elements.
// append stack to this stack
public Stack append(Stack stack) {
// create a new stack to return
Stack retStack = new Stack();
// copy the data from the current stack to the new, ensuring
// space for both
retStack.data = Arrays.copyOf(data, index + stack.index);
System.arraycopy(stack.data, 0, retStack.data, index,
stack.index);
// update the returned stack's index.
retStack.index = index + stack.index;
// return the stack.
return retStack;
}
This is only one possibility. The overall idea is to return a new stack to house any modifications to an existing stack without changing the existing stack. It all depends on how much flexibility you are permitted with your solution and the requirements of your instructor.
I am currently studying stacks and there is one thing that I do not understand. I have to create two constructors. What I don't understand is why do I have to set the top at -1 for my second constructor when my program already stacked some elements? Thanks
public stack () {
Array = new Object [MAX_ELEMENTS];
top = -1;
}
public stack (int elements) {
Array = new Object [elements];
top = -1;
}
why do I have to set the top at -1 for my second constructor
You don't, in general, but you do in this case because there are two separate constructors that don't call each other. There are several better solutions:
Initalize top inline, not in the constructor:
int top = -1;
Chain the constructors:
public stack () {
this(MAX_ELEMENTS);
}
public stack (int elements) {
Array = new Object [elements];
top = -1;
}
Both.
when my program already stacked some elements?
No it didn't. It just created an array of the size you specified.
Additionally to the other answer, you can also use an instance initializer:
{
top = -1;
}
It will be called regardless of the constructor user.
I have a bit of a problem. I'm making a Finite Automata checker.
Given an input, and the DFA, does it end on a accepting state.
My problem is creating a new DFA_State from another's target.
DFA_State state0, state1, curr_state, init_state, temp; //fine, I think
state0 = new DFA_State();
state1 = new DFA_State();
state0 = new DFA_State("State 0",true, state0, state1); //fine, I think
init_state = new DFA_State(state0); //fine, I think
but, this bit is throwing up problems.
temp = new DFA_State(curr_state.nextState(arr1[i]));
*
*
curr_state = new DFA_State(temp);
Thanks for any help,
Dave
Edit:
God I was retarded when I did this, AFAIK, I just wasn't thinking straight, added methods to set the values to the DFA_State object.
//in DFA_State class
public void set(DFA_State on_0, DFA_State on_1, Boolean is_accepting, String name){
this.on_0 = on_0;
this.on_1 = on_1;
this.is_accepting = is_accepting;
this.name = name;
}
//in main
DFA_State state0, state1, curr_state;
state0 = new DFA_State();
state1 = new DFA_State();
state0.set(state0, state1, false, "State 0");
state1.set(state1, state0, true, "State 1");
curr_state = state0;//initial state
//iterate across string input changing curr_state depending on char c
curr_state = getNextState(c);
//at end
if(curr_state.isAccepting())
System.out.println("Valid, " + curr_state.getName() + " is accepting);
else
System.out.println("Invalid, " + curr_state.getName() + " is not accepting);
In that first line, you declare the variables state0, state1, curr_state, init_state and temp as being variables of type DFA_State. However, that only declares them, they are not yet initialized. The next few lines are all okay. Second line creates a state without anything in it and assigns it to state0, so does the third line for state1. Fourth line overwrites your previous state0 assignment with a new DFA_State that has actual contents. Fifth line creates a DFA_State as a copy of state0 and assigns it to init_state.
Assuming there's nothing in between this and the first line of your second code block, now you'll get a problem. You're assigning temp with a new DFA_State that uses a copy-constructor with an argument relying on curr_state. But at that point, that variable hasn't been initialized yet. Just because it was declared doesn't mean it has somehow already been structured in memory. When you call nextState on it, there's simply no variable to resolve this to. Don't expect to get something like a pointer that will eventually point to a part of what you put in curr_state.
I'm just guessing, but from your code style I'd say you have a background in C or C++. Look into the differences between those languages and Java. If possible, I'd also advise you to make your DFA_State class immutable, since this is more reliable and will avoid mistakes. That means getting rid of the no-args constructor. Here's a reworking of it (not actually compiled, might contain errors):
package foundations.of.computing;
/**
*
* #author Kayotic
*/
class DFA_State {
private final String state;
private final DFA_State on_0;
private final DFA_State on_1;
private final boolean isAccepting;
//private DFA_State dummy;
public DFA_State(DFA_State arg) {
//this(arg.is_accepting(), arg.on0(), arg.on1());
state = arg.get_name();
isAccepting = arg.is_accepting();
on_0 = arg.on0();
on_1 = arg.on1();
}
public DFA_State(String name, Boolean accepting, DFA_State on0, DFA_State on1) {
state = name;
isAccepting = accepting;
on_0 = on0;
on_1 = on1;
}
public String get_name(){
return state;
}
public Boolean is_accepting() {
return isAccepting;
}
public DFA_State on0() {
return on_0;
}
public DFA_State on1() {
return on_1;
}
public DFA_State nextState(char i) {
if (i == '0') {
return on0();
} else if (i == '1') {
return on1();
} else {
System.out.println("Error with input");
return null;
}
}
}
Even if you can't make the instance variables final, it's best to at least make them private, since you already have methods for getting them.
There are better memory representations of DFAs than the object-oriented.
You should use a simple lookuptable:
int[] table = new int[vocabularyCount][stateCount];
Every State and every word gets a number, starting with 0.
Fill the table with the state transitions, or -1, if there is no transition. Now you just need the translation methods for the states and the words.
Heres a generic DFA algorithm:
public boolean checkSentence(String s, int[] finishes) {
// fill table
int state = 0; // assuming S0 is the start state
for (int i = 0; i < s.length(); i++) {
state = table[translate(s.charAt(i))][s];
}
for (int i = 0; i < finishes.length; i++) {
if (finishes[i] == state) {
return true;
}
}
return false;
}
The program is quite poorly written. Look at this in your FoundationsOfComputing.java:
state0 = new DFA_State();
state1 = new DFA_State();
state0 = new DFA_State("State 0",true, state0, state1);
You essentially created 3 instances of state - two instances which are not initialized (first two lines in your code) - all their instance variables are null.
Then you create the third instance, which you point to the first two uninitialized ones, and assign it to state0 variable. Please note, at this point, it is only the value of the variable that changes, not the values you passed in the DFA-State constructor!!! So, what you now have in state0 is a state that points to two uninitialized states.
Now let's look at the code further down in the FoundationsOfComputing.java:
while (i < arr1.length) {//loops through array
System.out.println(i + ". scan shows " + arr1[i]);
temp = new DFA_State(curr_state.nextState(arr1[i]));
System.out.println(" "+curr_state.get_name()+ " moves onto " + temp.get_name());
curr_state = new DFA_State(temp);
i++;
}
I am guessing this throws NullPointerException - that code moves to the on_0 state of state0 - which is a state that has not been initialized (all it's instance variables are null), so in the following pass of the loop, when it calls curr_state.nextState(whatever), it would return null and you are trying to pass that to the copy-constructor which would result in NPE.
Ok so we know this is homework. Let's do this instead of telling you the answer let's try and work through it on your own. If you are seeing a NullPointerException (NPE). Grab the second line of the exception:
java.lang.NullPointerException: null
at com.blah.blah.SomeObject.someMethod(SomeArgumentType):1234 <<< here
....
That 1234 is the line number in the file that contains SomeObject. If you goto that line number you can see exactly where the NPE is being generated from. For example if line 1234 was:
this.foo = bar.indexOf("caramel");
You can easily deduce what was null. No clue? Well this can never be null so this.foo isn't the problem. If this could be null you couldn't be inside that method because this points to the instance you are currently within. Therefore, the only other statement where a variable is being dereferenced is bar so bar must be null. Let's look at your code:
temp = new DFA_State(curr_state.nextState(arr1[i]));
Say you find out the line above is tossing an exception. Well there could be several things that could be null. curr_state could be null, or arr1 could be null in which case this line would blow up. However, if arr1[i] is null or curr_state.nextState() is returning null then you won't see the NPE pointing at this line, but would be coming out of the constructor should someone try to call methods on that method parameter.
Hopefully, this will give you the tools you need to track down problems in your application by understanding exception stack traces.