Odd ArrayList Index out of range Exception [duplicate] - java

This question already has answers here:
ArrayList initial capacity and IndexOutOfBoundsException [duplicate]
(3 answers)
Closed 7 years ago.
I'm attempting to create a program that will take a given word and find the list of words that could be made out of the letters inside the given word. Here's my code:
package wordfinder;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;
public class WordFinder {
public static void main(String[] args) throws IOException {
List<String> wordList1 = Files.readAllLines(Paths.get("res", "WordList1.txt"));
List<String> wordList2 = Files.readAllLines(Paths.get("res", "WordList2.txt"));
Scanner scan = new Scanner(System.in);
System.out.println("Please enter the string you would like this program to find words in.");
String wordToFind = scan.nextLine();
ArrayList<String> words = new ArrayList<>();
ArrayList<Character> charArray = new ArrayList<>();
char[] charList = wordToFind.trim().toCharArray();
for (int i = 0; i < charList.length; i++) {
charArray.add(charList[i]);
}
for (int i = 0; i < wordList1.size(); i++) {
char[] charsInWordToCheckAgainst = wordList1.get(i).toCharArray();
ArrayList<Boolean> containsLetter = new ArrayList<>(charsInWordToCheckAgainst.length);
for (int j = 0; j < charsInWordToCheckAgainst.length; j++) {
if (charArray.contains(charsInWordToCheckAgainst[j])) {
containsLetter.set(j, true);
}
}
if (areAllTrue(containsLetter)) {
words.add(wordList1.get(i));
}
}
for (int i = 0; i < wordList2.size(); i++) {
for (int j = 0; j < wordList2.get(i).length(); j++) {
char[] charsInWordToCheckAgainst = wordList2.get(i).toCharArray();
ArrayList<Boolean> containsLetter = new ArrayList(charsInWordToCheckAgainst.length);
for (int k = 0; k < charsInWordToCheckAgainst.length; k++) {
if (charArray.contains(charsInWordToCheckAgainst[k])) {
containsLetter.set(k, true);
}
}
if (areAllTrue(containsLetter)) {
words.add(wordList2.get(i));
}
}
}
System.out.println("Words found: " + words.size());
for(int i = 0; i < words.size(); i++) {
System.out.println("Word " + i + ": " + words.get(i));
try {
TimeUnit.MILLISECONDS.sleep(1);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
public static boolean areAllTrue(ArrayList<Boolean> bools) {
for (int i = 0; i < bools.size(); i++) {
if (!bools.get(i)) {
return false;
}
}
return true;
}
}
And here's the error I'm getting:
Please enter the string you would like this program to find words in.
abcdefghijklmnopqrstuvwxyz
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 2, Size: 0
at java.util.ArrayList.rangeCheck(ArrayList.java:653)
at java.util.ArrayList.set(ArrayList.java:444)
at wordfinder.WordFinder.main(WordFinder.java:36)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Process finished with exit code 1
For clarification, WordFinder.java:36 is containsLetter.set(j, true); in the wordList1 for loop. So I really just don't understand why the size of the array is 0. containLetter should not be 0.
UPDATE 1
Updated wordList1 for loop to this:
for (int i = 0; i < wordList2.size(); i++) {
for (int j = 0; j < wordList2.get(i).length(); j++) {
char[] charsInWordToCheckAgainst = wordList2.get(i).toCharArray()
ArrayList<Boolean> containsLetter = new ArrayList<>();
Collections.fill((List) containsLetter, charsInWordToCheckAgainst.length);
for (int k = 0; k < charsInWordToCheckAgainst.length; k++) {
if (charArray.contains(charsInWordToCheckAgainst[k])) {
containsLetter.set(k, true);
}
}
if (areAllTrue(containsLetter)) {
words.add(wordList2.get(i));
}
}
}
But that still gives me the same error.

According to javadoc for ArrayList constructor new ArrayList<>(charsInWordToCheckAgainst.length) accept single parameter - which is initial capacity of list. Capacity - not size.
The difference is as follow.
Size - is number of elements stored in the list.
Capacity - is initial array size created for this structure.
E.g. whenever you adding element to list it will check - do I have capacity for it and if not - re-allocate new array. Purpose of providing this parameter into constructor is to reduce amount of re-allocations. In order to pre-fill list - you need to put elements inside manually or use utility functions provided by 3-rd party libraries.

Related

How do I get rid of java.lang.NumberFormatException error

This code takes two txt files, reads them puts them in 2d arrays and should check if the numbers in the files are magic squares but it keeps returning NumberFormatException error. I'm new to java so if anyone could help me that would be great. I'm pretty sure the problem come from the txt file being string and the 2d array needing to be in int form. But how and where do I make that conversion on my code?
this is what i have:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.Scanner;
public class ms {
public static void main(String[] args) throws FileNotFoundException {
String filename1 = "magicSquaresData.txt", filename2 = "magicSquaresData.txt";
int nos[][] = null;
nos = getArray(filename1);
boolean b = isMagicSquare(nos);
printArray(nos);
if (b) {
System.out.println("It is a magic Square");
} else {
System.out.println("It is not a magic Square");
}
System.out.println("\n");
nos = getArray(filename2);
b = isMagicSquare(nos);
printArray(nos);
if (b) {
System.out.println("It is a magic Square");
} else {
System.out.println("It is not a magic Square");
}
}
private static int[][] getArray(String filename) throws FileNotFoundException {
String line;
int nos[][] = null;
int size = 0, rows = 0;
Scanner sc = null;
try {
sc = new Scanner(new File(filename));
while (sc.hasNext()) {
if (!sc.nextLine().isEmpty())
size++;
}
sc.close();
nos = new int[size][size];
sc = new Scanner(new File(filename));
while (sc.hasNext()) {
line = sc.nextLine();
if (!line.isEmpty()) {
String arr[] = line.split("\t");
for (int i = 0; i < arr.length; i++) {
nos[rows][i] = Integer.valueOf(arr[i]);
}
rows++;
}
}
sc.close();
} catch (FileNotFoundException e) {
System.out.println(e);
}
return nos;
}
private static void printArray(int[][] nos){
for(int i = 0; i<nos[0].length;i++) {
for (int j = 0; j < nos[0].length; j++){
System.out.printf("%-3d",nos[i][j]);
}
System.out.println();
}
}
private static boolean isMagicSquare(int[][] square) {
boolean bool = true;
int order = square.length;
int[] sumRow = new int[order];
int[] sumCol = new int[order];
int[] sumDiag = new int[2];
Arrays.fill(sumRow, 0);
Arrays.fill(sumCol, 0);
Arrays.fill(sumDiag, 0);
for (int row = 0; row < order; row++){
for (int col = 0; col < order; col++) {
sumRow[row] += square[row][col];
}
}
for (int col = 0; col < order; col++) {
for (int row = 0; row < order; row++) {
sumCol[col] += square[row][col];
}
}
for (int row = 0; row < order; row++) {
sumDiag[0] += square[row][row];
}
for (int row = 0; row < order; row++) {
sumDiag[1] += square[row][order - 1 - row];
}
bool = true;
int sum = sumRow[0];
for (int i = 1; i < order; i++) {
bool = bool && (sum == sumRow[i]);
}
for (int i = 0; i < order; i++) {
bool = bool && (sum == sumCol[i]);
}
for (int i = 0; i < 2; i++) {
bool = bool && (sum == sumDiag[i]);
}
return bool;
}
}
SUGGESTION:
Substitute nos[rows][i] = Integer.valueOf(arr[i]); for a custom method that will tell you WHERE the error is occurring.
EXAMPLE:
public static Integer tryParse(String text, int row, int i) {
try {
return Integer.parseInt(text);
} catch (NumberFormatException e) {
System.out.println("ERROR: row=" + row + ", i=" + i + ", text=" + text);
return null;
}
}
CAVEAT: This is for helping you troubleshoot ONLY. You definitely wouldn't want to release this in "production code" ;)
What is the NumberFormatException?
Thrown to indicate that the application has attempted to convert a string to one of the numeric types, but that the string does not have the appropriate format.
Offtopic:
A thing that i can notice is that both filesnames have the same name. So you will verify the same file 2 times.
String filename1 = "magicSquaresData.txt", filename2 = "magicSquaresData.txt";
I checked your program and you error appears when you put like this on a file:
1. 5 5
2. 5 5
So the error shows beacause you are trying to parse to int the String "5 5". So your code pick the all line and tries to convert to int and " " it's not an int. And there lives the NumberFormatException error.
How do to solve it?
The function that we will work on is the one that you pass from file to an array in
private static int[][] getArray(String filename) throws FileNotFoundException{
The of the function is after we read the file.
As you said, you are leading with a 2d array so to insert all the numbers we need to have loops for each dimension on the array.
So we will start from there.
I will use a while beacause we are dealing with a string and it's easier to verify the text that its left on the line. Will add a new int variable that starts in 0 to pass in every column of a line to use with the while loop. And with this we got this:
for (int i = 0; i < lines.length; i++) {
while(!"".equals(line)){
whileIterator++;
}
whileIterator = 0;
}
Next setep, we will divide in 2 behaviors because we will substring the String that has in the line, and will work differently when it's the last number that we are verifying:
for (int i = 0; i < lines.length; i++) {
while(!"".equals(line)){
if(whileIterator + 1 == size){//If its the last iteration that we need in a line
}else{//All other iterations
whileIterator++;
}
whileIterator = 0;}
To finalize let's add the new logic to insert in nos array. So lets pick all line for example 2 7 6 and we want to add the number 2, so lets do that. You just need to substring(int startIndex, int finalIndex) the line and add to the nos array. After that let remove the number and the space ("2 ") from the line that we are veryfying.
for (int i = 0; i < lines.length; i++) {
while(!"".equals(line)){
if(whileIterator + 1 == size){//If its the last iteration that we need
nos[rows][whileIterator] = Integer.parseInt(line.substring(0));//Add to array
line = "";//To not pass the while verification
}else{//All other iterations
nos[rows][whileIterator] = Integer.parseInt(line.substring(0, line.indexOf(" ")));//Add to array
line = line.substring(line.indexOf(" ") + 1);//remove the number we added behind
}
whileIterator++;
}
whileIterator = 0;}
And here you go, that how you add the numbers to an array and don't get the error.
If you need some further explanation just ask. Hope it helps :)

TimeLimitExceeded upon submission

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
class Main {
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
int t = Integer.parseInt(input.readLine());
for (int i = 0; i < t; i++) {
String[] arrayData = input.readLine().split(" ");
int[] cardsi = new int[arrayData.length];
int e = 0;
for(int a = 0; a < arrayData.length; a++){
cardsi[e] = Integer.parseInt(arrayData[a]);
e++;
}
int X = cardsi[0];
int N = cardsi[1];
long count = 0;
for (int j = 2; j < cardsi.length; j++) {
for (int l = 3; l <= (cardsi.length - 1); l++) {
if ((cardsi[j] + cardsi[l]) == X &&(j != l)) {
count++;
}
}
}
System.out.println((i + 1) + ". " + count);
}
}
}
Time limit exceeded error is appearing upon submitting this LCPC12F problem on spoj.. what might be a solution? Is scanner a major trouble for such error to appear?
Have you ever run those codes on IDE?
When I give the number to t element then arrayData (in this case, we should enter int type not String, because of the java.lang.NumberFormatException), it shows Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1 and int N = cardsi[1]; is the main problem on your code I think. This is because String[] arrayData = input.readLine().split(" "); size is 1 so you do not have cardsi[1] element on your int array

Code is throwing an IndexOutOfBoundsException? [duplicate]

This question already has answers here:
"Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0" with ArrayList?
(4 answers)
Closed 6 years ago.
Can anyone tell me why this code isn't working? It throws an IndexOutOfBoundsException.
package blok6afvink6;
/**
*
*/
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Scanner;
public class Blok6afvink6 {
public static void main(String[] args) throws FileNotFoundException {
//1st, use Scanner to readin all sequence names and sequences;
//create two arrayList to store sequence names and sequences;
ArrayList<String> name = new ArrayList<String>();
ArrayList<String> sequence = new ArrayList<String>();
Scanner ScanLine = new Scanner(new FileReader("OverlapGraph.txt"));
String seq = "";
while (ScanLine.hasNextLine()) {
String temp = ScanLine.nextLine();
if (temp.charAt(0) == '>') {
sequence.add(seq);
name.add(temp.substring(1));
seq = "";
} else {
seq += temp;
}
}
ScanLine.close();
sequence.remove(0);
sequence.add(seq);
//naam en seq printen
int Len = name.size();
for (int i = 0; i < Len; i++) {
System.out.println(name.get(i) + ": " + sequence.get(i));
}
//3rd, connect all sequences with O3 overlap, put the linked-names into a new string ArrayList
ArrayList<String> overLaps = linkOverlaps(name, sequence);
System.out.println("\nPrintout results:");
for (int i = 0; i < overLaps.size(); i++) {
System.out.println(overLaps.get(i));
}
}
private static ArrayList<String> linkOverlaps(ArrayList<String> name, ArrayList<String> sequence) {
ArrayList<String> overLap = new ArrayList<String>();
//int size = name.size();
for (int i = 0; i < name.size(); i++) {
int Len1 = sequence.get(i).length();
for (int j = 0; j < name.size(); j++) {
if (i != j && sequence.get(i).substring(Len1 - 3).equals(sequence.get(j).substring(0, 3))) {
String linked = name.get(i) + " " + name.get(j);
overLap.add(linked);
}
}
}
return overLap;
}
}
The error:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.rangeCheck(ArrayList.java:653)
at java.util.ArrayList.remove(ArrayList.java:492)
at blok6afvink6.Blok6afvink6.main(Blok6afvink6.java:36)
Line 36 referenced in the exception appears to be:
sequence.remove(0);
This can only fail with this exception if the list was empty.
So one has to assume that sequence.add(seq); is never called.
If that's OK and expected, you could check for empty first:
if (!sequence.isEmpty()) {
sequence.remove(0);
}
try
if(sequence.size() > 0) {
sequence.remove(0);
}
Look closely at the error message:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
It would seem that one of your collections has size 0. If so, that would cause this exception because you don't always check to make sure that the collections actually have any items before you try to access them.
Check sequence in particular.

Sorting strings alphabetically in an array. Java

I have to sort strings in an array for a school project. Our teacher won't allow us to use array,sort().
i have to use 2 sort methods but they aren't working too well.
The first one returns double of each value. ie John, jack, adam, tom will return adam,adam,jack,jack,john,john,tom,tom.
public static void sort() {
inputFileNames();//inputs list of names from a file.
for (int i = 0; i < size - 1; i++) {
for (int j = i + 1; j < size; j++) {
if (stArr[i].compareTo(stArr[j])>0) {
temp = stArr[i];
stArr[i] = stArr[j];
stArr[j] = temp;
}
}
}
display("The names are: ");// method to display array
System.out.println("");
}
the second sort doesn' run:
public static void bubbleSort() {
inputFileNames();
for (int i = size - 1; i >= 0; i--) {
for (int j = 0; j <= i; j++) {
if (stArr[j].compareTo(stArr[j+1])>0) {
temp = stArr[j];
stArr[j] = stArr[j + 1];
stArr[j + 1] = temp;
}
}
}
display("The names are: ");
System.out.println("");
}
input and display:
static void display(String heading) {
System.out.println(heading + "\n");
for (int i = 0; i < size; i++) {
System.out.println(stArr[i]);
}
}
static void inputFileNames() {
try {
Scanner scFile = new Scanner(new File("Names.txt"));
while (scFile.hasNext()) {
stArr[size] = scFile.nextLine();
size++;
}
} catch (FileNotFoundException ex) {
System.out.println("File not found.");
}
}
/* package codechef; // don't place package name! */
import java.util.*;
import java.lang.*;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
class Codechef
{
public static void main (String[] args) throws java.lang.Exception
{ Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int i,j;
String[] stArr = new String[n];
for(i=0;i<n;i++)
{
stArr[i]=sc.next();
// System.out.println(stArr[i]);
}
//inputs list of names from a file.
for (i = 0; i < n ; i++) {
for (j = i+1 ; j < n; j++) {
if (stArr[i].compareTo(stArr[j])>0)
{
String temp = stArr[i];
stArr[i] = stArr[j];
stArr[j] = temp;
// System.out.println(stArr[i]);
// System.out.println(stArr[j]);
}
}
}
for(i=0;i<n;i++)
{
System.out.println(stArr[i]);
}
// your code goes here
}
}
This Is the answer for first code. I am not good in file handling so you have to use your input method. I know Scanner thats why i have used here.
In Your Second Example Your j loop is wrong it should be for ( j = 0; j <= i-1; j++). And Please Mark It as answer if your problem is solved

Sorting of array

This is the text file:
1,2,8,4,5,6,7,7,
3,4,5,6,7,8,
5,6,7,8,9,9,
1,2,3,4,5,8,9,0
After ignoring the 1st column:
2,8,4,5,6,7,7,
4,5,6,7,8,
6,7,8,9,9,
2,3,4,5,8,9,0
I want to sort the array in descending order but I can't get it to work. This is the code that I have done so far:
Scanner scanner = new Scanner(new File("test.txt"));
int row = 0;
int col = 0;
while (scanner.hasNextLine())
{
String currentline = scanner.nextLine();
row++;
String[] items = currentline.split(",");
int[] intitems = new int[items.length];
for (int i = 1; i < items.length; i++)
{
intitems[i] = Integer.parseInt(items[i]);
System.out.print(intitems[i] + " ");
int temp = 0;
for (int j = 2; j < (items.length - i); j++)
{
temp = intitems[j - 1];
intitems[j - 1] = intitems[j];
intitems[j] = temp;
}
col = i;
}
col++;
System.out.println();
System.out.println("After sort: " + intitems);
System.out.println();
}
System.out.println("Row: " +row);
No need to complicate things:
for (int i = 1; i < items.length; i++) {
intitems[i - 1] = Integer.parseInt(items[i]);
}
Arrays.sort(intitems); // Ascending
Arrays.sort(intitems, Collections.reverseOrder()); // Descending
But if you really want to use a loop to sort the array (bubblesort) you need to compare the items you switch:
for (int i = 0; i < intitems.length - 1; i++) {
for(int j = i + 1; j < intitems.length; j++) {
if (intitems[i] > intitems[j]) {
int temp = intitems[j];
intitems[j] = intitems[i];
intitems[i] = temp;
}
}
}
If you want it sorted in descending order then just change the greater than (>) comparison to a lesser than (<) comparison:
if (intitems[i] < intitems[j]) {
private static void sortInDescending(int[] arrayObj)
{
int n = arrayObj.length;
int temp = 0;
for(int i=0; i < n; i++)
{
for(int j=1; j < (n-i); j++)
{
if(arrayObj[j-1] < arrayObj[j])
{
temp = arrayObj[j-1];
arrayObj[j-1] = arrayObj[j];
arrayObj[j] = temp;
}
}
}
}
Call method
sortInDescending(arrayinput);
You can use the Arrays.sort() with a custom comparator to make it descending.
String[] items = currentLine.split(",");
Integer[] intItems = new Integer[items.length];
for(int i=0; i<intItems.length; ++i) {
intItems[i] = Integer.parseInt(items[i]);
}
Comparator<Integer> comparator = new Comparator<Integer>() {
#Override
public int compare(Integer left, Integer right) {
return -Integer.compare(left, right);
}
};
Arrays.sort(intItems, comparator);
System.out.println(Arrays.toString(intItems));
}
Or you can sort the array in ascending order and reverse the array.
Arrays.sort(intItems);
Integer[] descending = new Integer[intItems.length];
int length = descending.length;
for(int i=0; i<length; ++i) {
descending[i] = intItems[length - 1 - i];
}
System.out.println(Arrays.toString(descending));
Other answers contain the bubble sort algorithm, where one element is compared to its successor. If the sort condition matches, then they get swapped. A slightly faster solution is insertion sort: in essence, it finds the maximal (minimal) value of the array and puts it to the front. There the implementation could look like this:
static int[] array = {2,8,4,5,6,7,7,};
public static void insertionSort(final int[] array) {
for(int i = 0; i < array.length; i++){
int maxValueIndex = findMaxValue(array, i);
int temp = array[i];
array[i] = array[maxValueIndex];
array[maxValueIndex]=temp;
}
}
private static int findMaxValue(final int[] array, int index) {
int value = Integer.MIN_VALUE;
for (int i = index; i < array.length; i++) {
if (array[i] > value) {
value = array[i];
index = i;
}
}
return index;
}
public static void main(final String[] args){
insertionSort(array);
System.out.println(Arrays.toString(array));
}
There you go :
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class SortTXT {
static File fout;
public static void main(String[] args) {
fout = new File("text.txt");
if (!fout.isFile())
{
System.out.println("text.txt - Parameter is not an existing file");
}
else
{
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(new FileInputStream(fout)));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
String line = null;
try {
while ((line = br.readLine()) != null) {
if (line.length()>2)
{
line.trim();
// crete an array from the line - seperate by ","
List<String> list = new ArrayList<String>(Arrays.asList(line.split(",")));
// remove the 1st number
list.remove(0);
//sorting the list
Collections.sort(list);
System.out.println();
System.out.println("After sort: ");
// print out the sorted array
for(String temp: list){
System.out.print("," + temp);
}
}
}
} catch (IOException e) {
}
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Hope This Helps :)
Dave.

Categories

Resources