Stack, Exception in thread "main" java.lang.NullPointerException [duplicate] - java

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 11 months ago.
In the following java program, I am trying to implement a stack using array
class stack{
int size, top;
int arr[];
stack(int n){
size = n;
top = -1;
int arr[] = new int[size];
}
void push(int x){
++top;
if(top >= size){
System.out.println("Stack overflow");
top = size-1;
}
else{
System.out.println("Data pushed: "+x);
arr[top] = x;
}
return;
}
void pop(){
if(top < 0){
System.out.println("Stack Underflow");
}
else{
System.out.println("Data popped: "+arr[top]);
--top;
}
return;
}
}
public class test{
public static void main(String[] args){
stack S = new stack(3);
S.push(5);
S.push(6);
S.push(7);
S.push(8);
S.pop();
S.pop();
S.pop();
S.pop();
}
}
After the first "push" operation the program throws the error: Exception in thread "main" java.lang.NullPointerException .
I tried initializing the array out of the constructor and it solves the problem, so I wanted to know what is wrong with the approach given above?
class stack{
int size, top;
int arr[] = new int[100];
stack(int n){
size = n;
top = -1;
//int arr[] = new int[size];
}

int size, top;
int arr[];
stack(int n){
size = n;
top = -1;
int arr[] = new int[size]; // these creates a local variable arr
}
Your problem here is that you are not instantiating your instance member, but creating a second, local array.
int size, top;
int arr[];
stack(int n){
size = n;
top = -1;
arr = new int[size]; // Don't redeclare arr, but use the existing one
}
This should fix the issue.

stack(int n){
size = n;
top = -1;
int arr[] = new int[size];
}
In the constructor , you are creating a new local variable arr[].
The instance variable is still uninitialised.
And by default, the value given to it is null.
Hence when you are trying to call an action on it, it is throwing Null Pointer Exception
Try this:
stack(int n){
size = n;
top = -1;
arr[] = new int[size];
}
For better understanding of variable scoping refer to this :https://docs.oracle.com/javase/specs/jls/se8/html/jls-6.html#jls-6.3

Related

How come I'm getting a null pointer exception [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 4 years ago.
I am getting a NullPointerException in the hanoi function when pushing the values from the input into the stack and I'm not sure why heres my code:
public class Hanoi {
public static Stack<Integer>[] towersOfHanoi = new Stack[4];
static int moves;
public static void hanoi(int n) {
for(int i = n; n > 0; i--) {
towersOfHanoi[1].push(i);
}
moveDisc(n, 1, 2, 3);
}
public static void moveDisc(int n, int j, int k, int l) {
moveDisc(n-1, j, k, l);
int i = towersOfHanoi[j].pop();
towersOfHanoi[k].push(i);
moves++;
moveDisc(n-1, l, j, k);
}
public static void main(String args[]) {
Scanner in = new Scanner(System.in);
System.out.println("Enter number of discs: ");
int n = in.nextInt();
in.close();
hanoi(n);
towersOfHanoi[1] = new Stack<Integer>();
towersOfHanoi[2] = new Stack<Integer>();
towersOfHanoi[3] = new Stack<Integer>();
System.out.println(moves);
You've initialized an array of Stacks, but you haven't actually allocated Stacks and put them in said Array. In your main() function, you should do something like:
for (int i = 0; i < 4; i++)
{
towersOfHanoi[i] = new Stack<Integer>();
}
Edit: Do this BEFORE you call hanoi(n). Otherwise, you're referencing objects before allocating them.

Array in two methods

import java.util.Scanner;
public class ld11 {
public static void firstMethod(int[] A) {
int size = A.length;
int equal[] = new int[size];
int less[] = new int[size];
int B[] = new int[size];
int i,j,k;
for(i=0; i<size; i++){
for(j=0;j<size;j++){
if(A[i]==A[j]){equal[i]++;}
else if(A[i]>A[j]){less[i]++;}
}}
for(i=0;i<size;i++){k=less[i];for(j=0;j<equal[i];j++){B[k+j]=A[i];}}
System.arraycopy(B, 0, A,0, A.length);
}
private static void sellaMethod(int[] A){
int t;
t=(int) (Math.log(A.length)/Math.log(2)-1);
int[] h = new int[t];
h[0]=1;
for(int i=1;i<h.length;i++)
h[i]=2*h[i-1]+1;
t--;
while(t>=0){
int inc=h[t];
t--;
for(int i=inc;i<A.length;i++){
int temp=A[i];
int j=i-inc;
while (j>=0 && A[j]>temp) {
A[j+inc]=A[j];
j=j-inc;
}
A[j+inc]=temp;
}
}
}
public static void main(String[] args) {
System.out.println("1st task");
System.out.print("Method(1/2): ");
Scanner sc = new Scanner(System.in);
int x;
if (sc.hasNextInt())
x = sc.nextInt();
else {System.out.println("input-output-error");
sc.close();
return;}
if(x!=1 && x!=2){
System.out.println("input-output-error");
return;}
System.out.print("Count: ");
int y;
if (sc.hasNextInt())
y = sc.nextInt();
else {
System.out.println("input-output-error");
sc.close();
return;}
int []A = new int[y];
System.out.println("Items:");
int i = 0;
do {if(sc.hasNextInt()){
int z = sc.nextInt();
A[i]=z;
i++;}
else{System.out.println("input-output-error");sc.close();return;}} while(i<y);
sc.close();
System.out.println("Sorted:");
if(x==1){firstMethod(A);}
else if(x==2){sellaMethod(A);}
for(i=0;i<y;i++){System.out.print(A[i]+" ");}
}
The user needs to choose which method it wants to use then write how many numbers and then write them, and programme sorts numbers in a way which is described in the method. With first method everything is okay, but with second shows errors :
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at ld11.sellaMethod(ld11.java:26) (h[0]=1; in this row))
at ld11.main(ld11.java:79) (else if(x==2){sellaMethod(A);} in this row
As you can see it is Shell sort method.
Could you please help?
The problem in line t=(int) (Math.log(A.length)/Math.log(2)-1);
If array has length less than 6 then t will be zero. So you'll create array with zero lenght. It's a bug. Probably you need some checks, probably another formula. Anyway, you have to review code.
As mentioned, your problem is your formula for getting the length of your h array.
A simple fix is just change this line:
t = (int) (Math.log(A.length) / Math.log(2) - 1);
to:
t = A.length;
as all you want is the new array to be same length as the initial array.

Given an array of integers, find out the third largest value in the array

public int thirdLargest(int[] arr){
int f_l = arr[0];
int s_l = arr[0];
int t_l = arr[0];
for(int i=1;i<arr.length;i++)
{
if (f_l < arr[i]){
t_l = s_l;
s_l = f_l;
f_l = arr[i];
}
else if (s_l < arr[i]){
t_l = s_l;
s_l = arr[i];
}
else if (t_l < arr[i]){
t_l = arr[i];
}
}
return t_l;
}
my code didn't passes some cases,any suggestion?
parameter {24,27,30,31,34,37,40,42}' , passes
parameter {2,-1,-2,-3,-4,-5}' , fails
This is simply cause by the fact that you initialize all values to arr[0]. If all elements are smaller than arr[0] this code won't update the values, even though the second-largest element for example wouldn't be arr[0]. Instead initialize the variables for the third/second/largest value with Integer.MIN_VALUE and start the search with the first element (index = 0) instead of the second.
There is actually a well-known algorithm for this, which is more generic than yours. It is called quick-select and looks like a quick sort with an optimization making it faster (linear time in average) : since we don't need to sort the array, we just recurse on the part of the array containing the index we are looking for (in your case, third item so index 2).
Here is an implementation in Java :
private static final Random rd = new Random();
public static int kthElement(int[] arr, int k) {
return kthElement(arr,k,0,arr.length);
}
private static T kthElement(int[] arr, int k, int min, int max) {
if (min < max - 1) {
int p = pivot(arr,min,max);
return p == k - 1 ? arr[p] :
p < k - 1 ? kthElement(arr,k,p + 1,max) : kthElement(arr,k,min,p);
}
return arr[min];
}
private static int pivot(int[] arr, int min, int max) {
int pivot = min + rd.nextInt(max - min);
swap(arr,pivot,max - 1);
pivot = min;
for (int i=min ; i<max ; i++)
if (arr[i] < arr[max - 1]) swap(arr,i,pivot++);
swap(arr,max - 1,pivot);
return pivot;
}
private static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
Well, as an alternative to your working code, here is a solution that will allow you to find the Nth largest integer in your array using Collections to do the heavy lifting:
import java.util.Arrays;
import java.util.Collections;
public class ArrayNthLargest {
public static int getNthLargest(int[] arrayInput, int n) {
Integer[] sortedArray = new Integer[arrayInput.length];
for (int i = 0; i < arrayInput.length; i++) {
sortedArray[i] = new Integer(arrayInput[i]);
}
Arrays.sort(sortedArray, Collections.reverseOrder());
return (sortedArray[n - 1]);
}
public static void main(String[] args){
int nth = new Integer(0);
int n = new Integer(3);
int[] testArray = {1,2,3,4,5,6,23,44,55,8,1};
nth = getNthLargest(testArray, n);
System.out.printf("The %d sorted array value is %d", n, nth);
}
}
This was actually an interesting question to me to do in O(n) complexity. I hope this solution is order n. I used an ArrayList as a stack (since Stack object won't allow addition of items in specific incidences (I've generalized it).
public int thirdLargest(int[] arr){
public int N_TH = 3; // Assuming this is nth largest you want
public ArrayList<Integer> largest = new ArrayList<Integer>(N_TH);
for(int i = 0;i<N_TH;i++)
largest.add(0); // initialize the ArrayList
for(int i = 0;i<arr.length;i++) {
for(int j=0;j<largest.size();j++){
if(arr[i] >= largest.get(j)) {
// Add the item at the correct index
// Pop the last element
largest.remove(largest.size()-1);
largest.add(j,arr[i]);
break;
}
}
}
return largest.get(N_TH);
}
Let me know if you find any problems with it, I might have mistyped part of trying to put it in OP's method.
EDIT won't work with negative numbers at the moment. You can find the smallest value in arr and initialize largest with that value. Then it'll also with negative numbers

Array index out of bounds java heap [duplicate]

This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 1 year ago.
I know this is an amaetuer error, i understand what it means but i dont understand why i cant fix it. Ive been trying everything. Im trying to take an array of type T and switch its values around so it correctly corresponds to the rules of a heap, where the parent is always greater than the 2 children. The error is in my while loop
please dont be harsh if its something easily fixable. ive been struggling heavily and cant seem to find an answer.
public class myheap<T extends Comparable<T>> extends heap<T>
{
// constructors of the subclass should be written this way:
public myheap(int max) { super(max); }
public myheap(T[] A) {super(A);}
public void buildheap(T[] Arr){
int size = Arr.length;
int startsize = (size-1)/2;
for(int i=startsize;i>0;i--){
int l = left(i);
int r = right(i);
T temp = null;
while((Arr[r]!=null) && Arr[i].compareTo(Arr[r])<0){
if (Arr[l].compareTo(Arr[r])>0){
temp = Arr[l];
Arr[l] = Arr[i];
Arr[i] = temp;
}//if left is greater than right
else //then right must be greater than parent
temp = Arr[r];
Arr[r] = Arr[i];
Arr[i] = temp;
}//whileloop
if((Arr[r]==null) && Arr[i].compareTo(Arr[l])<0)
temp = Arr[l];
Arr[l] = Arr[i];
Arr[i] = temp;
}//for
}//buildheap
public static void main(String[] args){
String[] array = {"SH","AH","AB","YA","AY","AA","AB","LM","LL","LO"};
myheap<String> New = new myheap<String>(array.length);
for(int i=0;i<array.length;i++){
New.insert(array[i]);
}//insert
New.buildheap(array);
New.drawheap();
for(int i=0;i<array.length;i++){
System.out.println(New.deletemax() + " ");
}//for
System.out.println();
} //main
}
Heap superclass that myheap is extending
/*
Polymorphic priority heaps, largest value on top.
Heap axiom. The value at every node cannot be smaller than the values
at each of its children nodes.
Use internal array to implement heap "tree", with index 0 representing
the root. Given node index i, left(i)= 2*i+1 and right(i)=2*i+2, while
parent(i) = (i-1)/2.
*/
class heap<T extends Comparable<T>>
{
protected T[] H; // internal array representing heap.
protected int size; // size of current heap, not same as H.length!
public int size() { return size; } // size is read-only externally.
public int maxsize() { return H.length; }
public heap(T[] A) { H = A; size=0; } // preferred constructor
public heap(int m) // will cause compiler warning (ok to ignore)
{
H = (T[]) new Comparable[m]; // downcast from Object is OK.
size = 0;
}
protected int left(int i) { return 2*i+1; }
protected int right(int i) { return 2*i+2; }
protected int parent(int i) { return (i-1)/2; }
// protected is important!
// lookup heap, without delete
public T getmax()
{
if (size<1) return null;
return H[0];
}
// insert x into heap: place at end, then propagate upwards
// returns false on failure.
public boolean insert(T x)
{
if (size > H.length-1) return false;
H[size++] = x; // place at end, inc size
// propagate upwards
int cur = size-1; // current position
int p = parent(cur);
while (cur>0 && H[cur].compareTo(H[p])>0)
{ // propagate upwards
T temp = H[cur];
H[cur] = H[p]; H[p] = temp;
cur = p; // switch current to parent
p = parent(cur); // recalc parent
}//while
return true;
}//insert
// deletetop: take last element, move to top, propagate downwards:
public T deletemax()
{
if (size<0) return null;
T answer = H[0];
H[0] = H[--size]; // place at top:
// now propagate downwards.
boolean done = false;
int i = 0; // current position
int c = 0; // swap candidate
while (c != -1)
{
int l = left(i);
int r = right(i);
c = -1; // swap candidate
if (l<size && H[l].compareTo(H[i])>0) c = l; // set candidate to left
if (r<size && H[r].compareTo(H[i])>0 && H[r].compareTo(H[l])>0) c=r;
if (c!= -1)
{
T temp = H[i]; H[i] = H[c]; H[c] = temp;
i = c;
}
}//while
return answer;
}//deletemax
// but search is not log(n). Why?
public boolean search(T x)
{
for(int i=0;i<size;i++) {if (x.compareTo(H[i])==0) return true;}
return false;
}
public void drawheap() // use only with heapdisplay.java program
{
heapdisplay W = new heapdisplay(1024,768);
W.drawtree(H,size);
}
}//heap
public class heaps14
{
/**public static void main(String[] args){
heap<Integer> HI = new heap<Integer>(200);
for(int i=0;i<100;i++) HI.insert((int)(Math.random()*1000));
HI.drawheap();
for(int i=0;i<100;i++) System.out.print(HI.deletemax() + " ");
System.out.println();
}//main**/
}
You may check for null in your while loop, (Arr[r]!=null) but the problem is that you can't even get a value from the array to determine if it's null or not. You should check the index is within the range before trying to access the value from the array, using r < Arr.length or similar.
(If null) isnt the problem, arrayIndexOutofBounds means you are geting a value of an array that isnt there
Eg. Array.length =5; and you search Array[6]; - out of bounds....
The problem i think is your method right(i);
which is. i*2+2 and the array
So change the for loop to this
for(int i=startsize-2;i>0;i--)
comment if this helps.

Null Pointer Exception for arrays

I'm getting a NullPointerException, it seems the program can't find nums (the array)
The Class:
/**
*Author: Chris Cherian
*Date: 4/30/14
*Desc: This program organizes numbers into 3 arrays - Even, Odd, and Negative.
*/
public class IntegerArray
{
/**
*The array that holds all the numbers.
*/
int nums [];
/**
*Holds count of the odds.
*/
private int oddCount = 0;
/**
*The numbers in the array.
*/
private int length;
/**
*Holds count of the positives.
*/
private int posCount;
public IntegerArray(int[] array)
{
nums = array;
}
/**
*The nuber of elements in the array.
*/
private final int TOTALNUMS = nums.length;
/**
*The array that holds all the even numbers.
*/
private int[] evens = new int[TOTALNUMS - this.getOddCount()];
/**
*The array that holds all the odd numbers.
*/
private int[] odds = new int[this.getOddCount()];
/**
*The array that holds all the negative numbers.
*/
private int[] negs = new int[TOTALNUMS - this.getPosCount()];
int evenCounter = 0;
/**
*Gathers the total number of odds
*#return The number of odd numbers
*/
public int getOddCount()
{
for(int i = 0; i <= TOTALNUMS; i++)
{
if(nums[i]%2 != 0)
{
oddCount++;
}
}
return oddCount;
}
/**
*Gathers number of positives
*#return posCount The number of positive numbers
*/
public int getPosCount()
{
for(int i = 0; i <= TOTALNUMS; i++)
{
if(nums[i] > 0)
{
posCount++;
}
}
return posCount;
}
public int[] organizeEvens()
{
for(int i = 0; i < nums.length; i++)
{
if(nums[i]%2 == 0)
{
evens[evenCounter] = nums[i];
evenCounter++;
}
}
return evens;
}
int oddCounter = 0;
public int[] organizeOdds()
{
for(int i = 0; i < nums.length; i++)
{
if(nums[i]%2 != 0)
{
odds[evenCounter] = nums[i];
oddCounter++;
}
}
return odds;
}
int negCounter = 0;
public int[] organizeNegs()
{
for(int i = 0; i < nums.length; i++)
{
if(nums[i]%2 == 0)
{
negs[negCounter] = nums[i];
negCounter++;
}
}
return negs;
}
}
The Client:
import java.util.Scanner;
public class IntegerArrayClient
{
public static void main(String[] jackofspades)
{
Die die1 = new Die(200);
Scanner keyboard = new Scanner(System.in);
System.out.println("How many numbers would you like to organize?");
int numbers = keyboard.nextInt();
int[] numbersarray = new int[numbers];
for(int i = 0; i < numbers; i++)
{
numbersarray[i] = (die1.Roll() - 200);
}
IntegerArray numholder = new IntegerArray(numbersarray);
int evenCount = (numbersarray.length - numholder.getOddCount());
for(int i = 0; i < evenCount; i++)
{
System.out.println(numholder.organizeEvens() + "\t");
}
}
}
The error message I get:
Exception in thread "main" java.lang.NullPointerException
at IntegerArray.<init>(IntegerArray.java:37)
at IntegerArrayClient.main(IntegerArrayClient.java:20)
The problem is that your code has an assumption that
private final int TOTALNUMS = nums.length;
would execute after the constructor, because textually it follows it. That is an incorrect assumption - this line executes before the constructor, at the time nums is still null. This is what is causing the exception.
To fix this problem, move the initialization of TOTALNUMS into the constructor:
private final int TOTALNUMS; // It's OK to leave it final - you are allowed to set it in the constructor
...
public IntegerArray(int[] array) {
nums = array;
TOTALNUMS = nums.length; // If nums is set to a non-null array, this would not cause an exception
}
Finally, note that there is little point in keeping a separate final variable for the length of nums, because its length is always available to you, and you do not need to "synchronize" the two if you decide to set nums to a different array later on.
This peice of code
private final int TOTALNUMS = nums.length;
is happening before nums has been initialized, it is still int nums []; - it has no size.
I assume that line 37 is this one:
private final int TOTALNUMS = nums.length;
The problem is that nums has not been initialized at that point, and it therefore still has its default initial value. Therefore, executing num.length throws an NPE.
How so?
Well you are initializing nums in the constructor. Bur the code in the constructor body is only executed AFTER the initializers for the instance variables have all been executed.
You need to initialize TOTALNUMS, evens, odds and so on in the constructor, since they all depend on the value passed in the constructor's array parameter.
You need to lookup up member initializers and when they run in relation to the constructor. They run before the constructor. Only after that (during the constructor) are you initializing num, and that is after you've tried to use num.Length.
Move the code that depends on nums.length to the constructor, after you've assigned nums, or in a method that is called after the object is fully created (ie. don't to it in the constructor at all, add another method on the class that returns the length).
Trying to do too much in the initializers is causing trouble.
See the first answer in this question:
Java Static Initialization Order
Or the Java rules on initialization order:
http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4.2
All these lines of code are wrong because these lines are executed as the object is created, prior to the constructor that initializes nums.
private final int TOTALNUMS = nums.length;
private int[] evens = new int[TOTALNUMS - this.getOddCount()];
private int[] odds = new int[this.getOddCount()];
private int[] negs = new int[TOTALNUMS - this.getPosCount()];
I suggest converting "evens" to "getEvens()" and calling getEvens() from main, not from the initializer.
Same for each of the other fields, convert to methods that are called later.

Categories

Resources