java.lang.ArrayIndexOutOfBoundsException: 4 Error - java

I'm new to coding and I've been writing this code and trying to make it work but every time I run it it crashes. I've looked things up and will writing this code I've followed java's website on how to properly write down code as well as this site.
Anyways, it would be greatly appreciated if someone can explain to me why this is not working because it seems to me like the logic is there but I don't get why it crashes.
My code:
import java.util.Scanner;
import java.lang.String;
import java.util.*;
public class Question1
{
public static void main(String[] args)
{
Scanner keyboard= new Scanner(System.in);
System.out.println("Enter either letters or numbers and I'll magically tell you if they are consecutive :D");
String inputedString= keyboard.nextLine();
boolean consecutiveOrNot=isConsecutive(inputedString);
System.out.println("Drum rolls...... Is it consecutive: "+ consecutiveOrNot); //Problem with this line?
}
public static boolean isConsecutive(String inputedString)
{
//Storing string's units into an array and converting to UpperCase if necessary
//and storing string's numerical value into the variable 'arrayCharToInt'
char[] charIntoArray= new char[inputedString.length()];
int[] arrayCharToInt= new int[inputedString.length()];
for (int i=0;i<inputedString.length();i++ )
{
charIntoArray[i]=inputedString.charAt(i);
if (Character.isLetter(charIntoArray[i]) && Character.isLowerCase(charIntoArray[i]))
{
charIntoArray[i]= Character.toUpperCase(charIntoArray[i]);
}
arrayCharToInt[i]=(int) charIntoArray[i];
}
// The next if statements and the methods that they call are used to verify
//that the content of the initial string is either letters or numbers, but not both together
boolean[] continuous= new boolean[arrayCharToInt.length];
boolean[] testContNumbersDecreasing= new boolean[arrayCharToInt.length];
boolean[] testContNumbersIncreasing= new boolean[arrayCharToInt.length];
boolean[] testContLettersDecreasing= new boolean[arrayCharToInt.length];
boolean[] testContLettersIncreasing= new boolean[arrayCharToInt.length];
Arrays.fill(continuous, true);
if (lowestValue(arrayCharToInt)>=65 && highestValue(arrayCharToInt)<= 90)
{
for (int x=0;x<arrayCharToInt.length ;x++ )
{
testContLettersIncreasing[x]=((arrayCharToInt[x+1]-arrayCharToInt[x]== 1) || (arrayCharToInt[x+1]-arrayCharToInt[x]== -25));
testContLettersDecreasing[x]=((arrayCharToInt[x]-arrayCharToInt[x+1]== 1) || (arrayCharToInt[x]-arrayCharToInt[x+1]== -25));
}
return (Arrays.equals(continuous,testContLettersIncreasing) || Arrays.equals(continuous,testContLettersDecreasing));
}
else if ((lowestValue(arrayCharToInt) >= 48) && (highestValue(arrayCharToInt)<= 57))
{
for (int x=0;x<arrayCharToInt.length ;x++ )
{
testContNumbersIncreasing[x]=((arrayCharToInt[x+1]-arrayCharToInt[x]== 1) || (arrayCharToInt[x+1]-arrayCharToInt[x]== -9));
testContNumbersDecreasing[x]=((arrayCharToInt[x]-arrayCharToInt[x+1]== 1) || (arrayCharToInt[x]-arrayCharToInt[x+1]== -9));
}
return (Arrays.equals(continuous,testContNumbersIncreasing) || Arrays.equals(continuous,testContNumbersDecreasing));
}
else
{
return false;
}
}
public static int lowestValue(int[] array)
{
int lowest=array[0];
for (int counter=0; counter< array.length; counter++)
{
if( lowest>array[counter])
lowest= array[counter];
}
return lowest;
}
public static int highestValue(int[] array)
{
int highest=array[0];
for (int counter=0; counter< array.length; counter++)
{
if( highest<array[counter])
highest= array[counter];
}
return highest;
}
}
The main method seems to be fine because it put everything in the isConsecutive method as a comment except for 'return true;' and indeed the program ran and printed true. So I know the problem lies somewhere in the second method.
If there's anything that I did not do right please tell me and that would be greatly appreciated. After all I'm still learning.
Thanks

All of your calls to arrayCharToInt[x+1] are going to go out of bounds on the last iteration of the loop they're in (for example, if arrayCharToInt.length equals 5, the highest that x is going to go is 4. But then x+1 equals 5, which is out of bounds for an array with five cells). You'll need to put in some sort of if( x == arrayCharToInt.length - 1) check.

in the method isConsecutive inside the for loop: for (int x=0;x<arrayCharToInt.length ;x++ ) , you have used arrayCharToInt[x+1]
if the arrayCharToInt lenth is 4 , then you have arrayCharToInt [0] to arrayCharToInt [3].
now consider this statement:arrayCharToInt[x+1]
when x is 3 this statement will evalueate to arrayCharToInt[4] resulting in array index out of bounds exception

This error throw when something went wrong in the Array calling function.
You got the length and make it print.
for eg:
int a[] = {1,2,3,4}
Length of this array is,
int length = a.length
So length = 4 but highest index is 3, not 4. That means index of the array started with 0. So you have to print:
arr[length-1];
In your program,
x == arrayCharToInt.length - 1

Related

JAVA: What am I doing wrong?

I am trying to determine the Hamming distance between two arrays of ints. Pre: aList != null, bList != null, aList.length == bList.length; Post: return the Hamming Distance between the two arrays of ints. I am not sure what I am doing wrong, I am just now starting to learn how to code. Any help is appreciated. Thanks in advance :)
Here is my code:
public class test {
public static int hammingDistance(int[] aList, int[] bList) {
// check preconditions
if (aList == null || bList == null || aList.length != bList.length)
throw new IllegalArgumentException("Violation of precondition: " +
"hammingDistance. neither parameter may equal null, arrays" +
" must be equal length.");
//Starting a counter
int counter = 0;
System.out.println("test");
//checking to see if there is a mismatch in the values of the two given arrays
for (int i = 0; i < bList.length; i++) {
if (bList[i] != aList[i]) {
//increasing counter everytime there is a mismatch
counter++;
}
}
return counter;
}
public static void main(String[] args) {
int[] aList = { 1,3,3,4 };
int[] bList = { 1,2,10,4 };
System.out.println(hammingDistance(aList, bList));
}
}
Updated Code
You are resetting the counter to zero whenever there is a match. So counter in never effective. Remove the else part of the code.
You are resetting the counter when two elements are equal (see your else statement). You shouldn't be doing anything when two called are equal.
Hope it helps,

Calling method from another class that's an array

I am calling a method from another class. The method contains an integer array. I am trying to stay away from inputting the index manually.
I am trying to search for numbers within a range.
example:
ArrayList: {1,5}, {5,10}, {10,15}
Input: enter 3
Process: search for number within range
output: 1,5
The driver class is storing the objects from the main class called Numbers into ArrayList. The main class have an accessor call getNumbers. getNumbers contains an integer array with 2 elements. The driver is calling getNumbers to validate the entry that users input.
The code below works but I'm told it's consider bad coding to code entering the indexes. I want to know how to output the array from getNumber method without knowing the array length of getNumber?
example of what I have:
for(int i = 0; i < example.size(); i++)
//number is the integer that is inputted.
if(example.get(i).getNumbers()[1] > number &&
example.get(i).getNumbers()[0] <= numbers)
System.out.println(example.get(i));
Should I add another for loop?
example of what I am thinking of:
for(int i = 0; i < example.size(); i++)
for(int j = 0; j < example.get(i).getNumbers.length; j++){
if(example.get(i).getNumbers()[j] > number &&
example.get(i).getNumbers()[j] <= numbers)
System.out.println(example.get(i));
}
}
Edit: Changed how I worded some things and fixed the code of what I think I should do.
The code below works but I'm told it's consider bad coding to code
entering the indexes. I want to know how to output the array from
getNumber method without knowing the array length of getNumber ?
If you don't want to do the validations with array indexes for your first element and second element in the array, then you can solve the problem by modifying your Numbers class as shown below:
(1) Define two int variable members (currently you have only one)
(2) Add a method isInLimits(int input) to validate the range
(3) Override toString() which can be used to print the object as String
Numbers class (modified):
public static class Numbers {
private int firstElement;
private int secondElement;
public int getFirstElement() {
return firstElement;
}
public void setFirstElement(int firstElement) {
this.firstElement = firstElement;
}
public int getSecondElement() {
return secondElement;
}
public void setSecondElement(int secondElement) {
this.secondElement = secondElement;
}
//checks the input is in the range of this object elements
public boolean isInLimits(int input) {
if(input >= firstElement && input < secondElement) {
return true;
} else {
return false;
}
}
#Override
public String toString() {
return "{"+firstElement+","+secondElement+"}";
}
}
Usage of Numbers Class:
public static void main(String[] args) {
int userInput = 10; //get it from user
List<Numbers> example = new ArrayList<>();
//Add Numbers objects to example list
for(int i=0;i< example.size();i++) {
Number numberTemp = example.get(i);
//call Numbers object's isInLimits
if(numberTemp.isInLimits(userInput)) {
System.out.println(numberTemp);
}
}
}

NullPointerException in the push() part of a stack implementation in a java program

My code is basically a program to check whether it is possible to use the ordered sequence 1,2,3..,n to generate a permutation of this sequence as specified by the user using a stack as temporary storage structure. The user has the option of entering n and the permutation he'd like to see generated using 2 methods; either through a text file or directly in the command line.
So, for example if the user enters 5 1 3 5 4 2, the n would be interpreted as the first number, i.e. 5 and then the rest of the digits is the permutation he'd like to see if it's possible to generate starting from 1 2 3 4 5 (Note that 1 2 3 4 5 is ordered and 1 is at the top of that stack). Here you'd have 1 being used directly, then 2 being stored in a stack, then 3 being used, then 4 stored on top of 2, then 5 being used, then 4 popped out followed by 2 being popped to generate the permutation.
The problem I'm having is my program faces a NullPointerException whenever I try to generate the starting stack of 1 2 3 ... n. It points to the last line of this block of code:
public static void main(String args[])
{
int[] arr;
arr = null;
try
{
if(args[0].charAt(0) == '2')
{
try
{
FileInputStream file = new FileInputStream(args[1]);
arr = input(file);
}
catch (FileNotFoundException e)
{
System.out.println("File not found.");
System.exit(0);
}
}
else if (args[0].charAt(0) == '1')
{
arr = input();
}
else
{
System.out.println("Please enter a valid input option.");
System.exit(0);
}
}
catch (ArrayIndexOutOfBoundsException e)
{
System.out.println("Please enter a valid input option.");
System.exit(0);
}
int x;
x = arr.length;
System.out.println(x);
ArrayPerm start = new ArrayPerm(x);
ArrayPerm temp = new ArrayPerm(x);
for (int i = 0; i < x; i++)
{
*start.push(x - i);*
}
And it also points to:
public void push(int j)
{
top++;
Stack[top] = j;
}
The ArrayPerm class is basically the stack implementation.
I tried doing this:
public void push(Integer j)
{
if (j == null)
{
throw new NullPointerException("NULL ELEMENT!");
}
else
{
top++;
Stack[top] = j;
}
}
But it's still showing the exception. If anyone could point me in the right direction I'd really appreciate it. I've spent an hour looking for the problem in my code without result.
So, thanks in advance!
EDIT: This is how the class is defined, so Stack shouldn't be initialized?
public class ArrayPerm
{
private int[] Stack;
private int top;
public int size;
public ArrayPerm(int n)
{
size = n;
int[] Stack = new int[n];
top = -1;
}
You're shadowing the variable Stack. Replace
int[] Stack = new int[n];
with
stackArray = new int[n];
You haven't initialized the 'Stack' member variable.

Learning to debug in Java

I'm both learning to use the JPDA on Netbeans and solving the Prime Generator problem of Sphere's Online Judge.
I've been reading this tutorial on netbeans.org about he JPDA, but haven't found it of much help.
This code, which is based on a Sieve of Eratostenes implementation provided by starblue here, is running like this:
2
1 10
//here the primes between 1 and 10 should print
3 5
//here the primes between 3 and 5 should print
package sphere;
/**
*
* #author Administrator
*/
//import java.util.ArrayList;
import java.util.BitSet;
import java.lang.Math.*;
import java.util.ArrayList;
public class Main
{
public static int ApproximateNthPrime(int nn)
{
double n = (double)nn;
double p;
if (nn >= 7022)
{
p = n * Math.log(n) + n * (Math.log(Math.log(n)) - 0.9385);
}
else if (nn >= 6)
{
p = n * Math.log(n) + n * Math.log(Math.log(n));
}
else if (nn > 0)
{
p = new int[] { 2, 3, 5, 7, 11 }[nn - 1];
}
else
{
p = 0;
}
return (int)p;
}
// Find all primes up to and including the limit
public static BitSet SieveOfEratosthenes(int limit)
{
final BitSet primes = new BitSet();
primes.set(0,false);
primes.set(1,false);
primes.set(2,limit,true);
for (int i =0; i*i<limit;i++)
{
if (primes.get(i))
{
for (int j=i*1; j<limit;j+=1)
{
primes.clear(j);// hace que el indice j sea false (no primo)
}
}
}
return primes;
}
public static ArrayList<Integer> GeneratePrimesSieveOfEratosthenes(int n)
{
int limit = ApproximateNthPrime(n);
BitSet bits = SieveOfEratosthenes(limit);
ArrayList <Integer> primes = new ArrayList<Integer>();
for (int i = 0, found = 0; i < limit && found < n; i++)
{
if (bits.get(i))
{
primes.add(i);
found++;
}
}
return primes;
}
public static void main (String[] args) throws java.lang.Exception
{
java.io.BufferedReader r = new java.io.BufferedReader (new java.io.InputStreamReader (System.in));
String s;
s= r.readLine();
int test_cases = Integer.parseInt(s);
int case_counter =0;
while (case_counter<test_cases) {
// System.out.println(s);
s = r.readLine();
String [] splitted = s.split(" ");
int lower_bound = Integer.parseInt(splitted[0]);
int upper_bound = Integer.parseInt(splitted[1]);
ArrayList <Integer> primesList= GeneratePrimesSieveOfEratosthenes(upper_bound);
for (int i =0; i<primesList.size();i++){
if (primesList.get(i)<=lower_bound)System.out.println(primesList.get(i));
}
case_counter++;
System.out.println(" "); // space that separates test cases
}
}
}
I know that the ArrayList primesList isn't getting initialized and I'm suspicious of this bit of code, cause honestly, I don't quite understand it:
if (primes.get(i))
{
for (int j=i*1; j<limit;j+=1)
{
primes.clear(j);
}
}
It occurred to me to use a conditional breakpoint here with the condition of:
primes.get(j)==false
But I'm not sure if I'm able to get meaningful info this way. These are the screens I'm getting:
alt text http://img525.imageshack.us/img525/6238/breakpoints.jpg
alt text http://img98.imageshack.us/img98/5262/watchesz.jpg
I don't know how to get useful info out of this.
My questions are:
a)I want to watch the primes BitSet as its going through this loop.
How do I do that?
b) What's exactly wrong with this code?
How did you spot it using the debugger?
Please, mention the step-by-step process.
So, I extracted out the following method:
private static void printPrimes(int lower_bound, int upper_bound) {
ArrayList<Integer> primesList = GeneratePrimesSieveOfEratosthenes(upper_bound);
for (int i = 0; i < primesList.size(); i++) {
if (primesList.get(i) <= lower_bound)
System.out.println(primesList.get(i));
}
}
and changed the main() method to just call that with a couple of arbitrary arguments (10 and 100), because I didn't want to mess around with the console and the debugger at the same time. I then (I'm using Eclipse) put ordinary breakpoints at the beginning and end lines of ApproximateNthPrime(), SieveOfEratosthenes() and GeneratePrimesSieveOfEratosthenes() to make sure they were being called. (By the way, Java convention, unlike C#, is for method names to start with a lower-case letter.)
All that was without bothering to understand the code. :) However, after the first run-through, it was pretty clear that the problem is that the BitSet produced by SieveOfEratosthenes() is always empty (or rather, always entirely false). I haven't used the NetBeans debugger, but I suspect the "Local Variables" tab is your friend here.
I'm not going to do your homework for you. :) But the idea of the Sieve of Eratosthenes is to skip the prime numbers and only eliminate the non-primes. Examine your SieveOfEratosthenes() method and ask yourself: when will it skip a number?

Is Levenshtein's distance the right way to tackle this Edit Steps problem?

I'm familiar with Levenshtein's distance, so I decided I would use it to solve UVA's Edit Steps Ladder problem.
My solution is:
import java.io.*;
import java.util.*;
class LevenshteinParaElJuez implements Runnable{
static String ReadLn(int maxLength){ // utility function to read from stdin,
// Provided by Programming-challenges, edit for style only
byte line[] = new byte [maxLength];
int length = 0;
int input = -1;
try{
while (length < maxLength){//Read untill maxlength
input = System.in.read();
if ((input < 0) || (input == '\n')) break; //or untill end of line ninput
line [length++] += input;
}
if ((input < 0) && (length == 0)) return null; // eof
return new String(line, 0, length);
}catch (IOException e){
return null;
}
}
public static void main(String args[]) // entry point from OS
{
LevenshteinParaElJuez myWork = new LevenshteinParaElJuez(); // Construct the bootloader
myWork.run(); // execute
}
public void run() {
new myStuff().run();
}
}
class myStuff implements Runnable{
public void run(){
ArrayList<String> theWords = new ArrayList<String>();
try
{
/// PLACE YOUR JAVA CODE HERE
String leido=LevenshteinParaElJuez.ReadLn(100);
//System.out.println("lo leido fue "+leido);
while (leido.length() != 0){
theWords.add(leido);
leido=LevenshteinParaElJuez.ReadLn(100);
}
}catch(Exception e){
System.out.println("El programa genero una excepcion");
}
int maxEdit=0;
int actualEdit=0;
int wordsIndex1 =0, wordsIndex2=0;
while (wordsIndex1<= theWords.size())
{
while (wordsIndex2<= theWords.size()-1){
actualEdit=Levenshtein.computeLevenshteinDistance(theWords.get(wordsIndex1),theWords.get(wordsIndex2));
if (actualEdit>maxEdit){maxEdit=actualEdit;}
wordsIndex2++;
}
wordsIndex1++;
}
System.out.println(maxEdit+1);
}
}
class Levenshtein {
private static int minimum(int a, int b, int c) {
if(a<=b && a<=c)
return a;
if(b<=a && b<=c)
return b;
return c;
}
public static int computeLevenshteinDistance(String str1, String str2) {
return computeLevenshteinDistance(str1.toCharArray(),
str2.toCharArray());
}
private static int computeLevenshteinDistance(char [] str1, char [] str2) {
int [][]distance = new int[str1.length+1][str2.length+1];
for(int i=0;i<=str1.length;i++)
distance[i][0]=i;
for(int j=0;j<=str2.length;j++)
distance[0][j]=j;
for(int i=1;i<=str1.length;i++)
for(int j=1;j<=str2.length;j++)
distance[i][j]= minimum(distance[i-1][j]+1,
distance[i][j-1]+1,
distance[i-1][j-1]+
((str1[i-1]==str2[j-1])?0:1));
return distance[str1.length][str2.length];
}
}
With this input:
cat
dig
dog
fig
fin
fine
fog
log
wine
it produces the correct output for this sample:
5
The judge is rejecting my answer. This is my first attempt at solving an online judge's problem, and I think I maybe forcing a correct answer here:
System.out.println(maxEdit+1);
since maxEdit has a value of 4 when computed simply with Levenshtein. Is that what's going on?
Levinshtein is relevant, but will not give you a value used in your output. In this problem, use it to determine if two words have an edit distance of exactly 1, indicating the two words compared are adjacent in the edit step ladder.
Iterate over the words in the dict. and if the next word has an edit distance of 1 from the current word, you may make that the current word, otherwise it must be skipped.
The trick to this problem is finding all possible sequences - just because the next word has an edit distance of 1 doesn't mean using it in the ladder will give you the longest possible ladder.
The problem states that you are to find the longest lexicographically ordered (i.e. alphabetical) sequence in the dictionary, such that each word in the sequence is formed by adding, deleting, or changing one letter.
So the 5 in the sample result is for the sequence (dig, fig, fin, fine, wine).
I don't think Levenshtein is particularly relevant to this problem, though maybe I am just not imaginative enough. Levenshtein doesn't capture the requirement that each step must be in the dictionary, and later in the dictionary.

Categories