No Such Element Exception when reading from a file - java

I understand that this is a commonly asked question, however, I'm not sure why I'm getting the error even after doing research.
import java.io.*;
import java.util.*;
public class readfile {
private Scanner x;
public void openFile(){
try{
x = new Scanner(new File("input.txt"));
}
catch(Exception e){
System.out.println("Oh noes, the file has not been founddd!");
}
}
public void readFile(){
int n = 0;
n = Integer.parseInt(x.next()); //n is the integer on the first line that creates boundaries n x n in an array.
System.out.println("Your array is size ["+ n + "] by [" + n +"]");
//Create n by n array.
int[][] array = new int[n][n];
//While there is an element, assign array[i][j] = the next element.
while(x.hasNext()){
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
array[i][j] = Integer.parseInt(x.next());
System.out.printf("%d", array[i][j]);
}
System.out.println();
}
}
}
public void closeFile(){
x.close();
}
}
I'm reading a text file that contains an adjacency matrix, where the first line indicates how large the matrix will be. ie) line 1 reads 5. Therefore I create a 2d array that is 5x5. The problem I'm having is after I read the file and print it, I get a NoSuchElement Exception. Thanks ahead of time!
Note: I am curious, I've seen that I need to user x.hasNext() when in a loop, so I do not assume there is input when there isn't. However, I've done this. Not sure what the problem is.
Output:
Your array is size [7] by [7]
0110011
1000000
1001000
0010001
0000001
1000001
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at readfile.readFile(readfile.java:32)
at verticies.main(verticies.java:8)

It looks like your code is reading a whole line as an int, is each of those numbers:
0110011 1000000 1001000 0010001 0000001 1000001
meant to be the 7 digits forming each row?
If that is the case, you need to split each value into the its component parts for its corresponding sub array.
In which case, use this section of code instead:
while(x.hasNext()){
for(int i = 0; i < n; i++){
String line = x.next();
for(int j = 0; j < n; j++){
array[i][j] = line.charAt(j) - '0';
System.out.printf("%d", array[i][j]);
}
System.out.println();
}
}

Related

Reading a string splitting it and assigning values to 2D array in JAVA

I am trying to split a string with " "(space) and assigning each value on row to each respective array.
The input file contains:
4
2 2
1 3
4 7
3 4
The first line of the file has a single integer value N which is number of jobs.
The next N lines will represent a job, each with 2 values.
How do I start reading from second line from a Input file?
I want to split from Second line and assign it to 2D array. So if (2,2) is there on second line, then 2 should be assigned to array[0][0] and the other 2 to array[0][1]. For next line 1 should be assigned to array[1][0] and 3 should be assigned to array[1][1].
int num = scan.nextInt(); // taking number of jobs from first line
int[][] array = new int[num][num];
while (scan.hasNext()) //It reads till file has next line
{
String str = scan.nextLine();
for (int i = 0; i < num; i++) {
for (int j = 0; j < num; j++) {
array[i][j] = scan.nextInt();
}
}
}
Had done till here, couldn't figure out further.
int[][] array = new int[num][num];
Wrong dimensions of the array, for N = 4 you create array of 4 * 4, not 4 * 2.
Since the number of columns is fixed in your case, you should create array as new int[num][2] and update reading of the data accordingly.
String str = scan.nextLine();
for (int i = 0; i < num; i++) {
for (int j = 0; j < num; j++) {
array[i][j] = scan.nextInt();
}
}
Reading a line just to skip it may be redundant if you use Scanner to read the integer numbers using nextInt. So actually you do NOT need to read the data line by line, then split each line into String parts, and convert each part into a number because Scanner class takes care of it.
Also, the innermost loop tries to read N numbers per array row, while it's better to refer actual length of the array in the row.
Thus, it should be ok just to read the data according to the task using Scanner only:
int num = scan.nextInt(); // taking number of jobs from the first line
// preparing array of N rows and 2 columns
int[][] array = new int[num][2];
for (int i = 0; i < num; i++) {
for (int j = 0; j < array[i].length; j++) { // reading 2 ints per row
array[i][j] = scan.nextInt();
}
}
You can make it a lot easier by just ignoring the first line and letting Java do the hard work:
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.stream.Stream;
import java.util.Arrays;
public class FileToArray {
public static void main(String[] args) {
try {
try (Stream<String> stream = Files.lines(Path.of("arr.txt"))) {
String[][] nums = stream.skip(1).map(s -> s.split(" ")).toArray(String[][]::new);
System.out.println(Arrays.deepToString(nums));
}
} catch (Throwable t) {
t.printStackTrace();
}
}
}

turning an array of strings into a 2d array of chars

my code reads input from a file that has a maze written inside, inside the file looks like this.
7 7
GOOOOXO
XXOXOOX
OXOOOXX
XXXOOXO
XXXXOXX
SOOOOOX
XXXXXXX (these are each on a separate line not sure how to show that here)
the numbers are the dimensions and G is goal S is start, that doesn't really matter for now. I read the file into an array of Strings line by line. So my array looks like this {"GOOOOXO",...,"XXXXXXX"} now I want to convert the strings to a 2d array of chars where the characters are stored the same way as the maze is displayed above.
The first nested for loop just reads the files input and saves each line as a string in the array, the second array is meant to convert the strings into characters to save them into the 2d array and still manage to keep the shape of the maze. I get an array index out of bounds exception. But to be honest with you after hours of being stuck on this my brain is fried, I can't figure out my issue.
int dimensionsX = input.nextInt();
int dimensionsY = input.nextInt();
String[] lines = new String[dimensionsY];
char[][] maze2 = new char[dimensionsX][dimensionsY];
for (int j = 0; j < dimensionsY; ++j) {
if (input.hasNextLine()) {
lines[j] = input.nextLine();
System.out.println(lines[j]);
//System.out.println(j);
}
}
for (int i = dimensionsX; i > 0; --i) {
for (int j = dimensionsY; j > 0; --i) {
maze2[i][j] = lines[i].charAt(j);
System.out.print(maze2[i][j]);
if (i == lines.length) {
System.out.println();
}
}
}
For example:
int dimensionsX = input.nextInt();
int dimensionsY = input.nextInt();
String[] lines = new String[dimensionsY];
char[][] maze2 = new char[dimensionsY][];
for (int j = 0; j < dimensionsY; ++j) {
if (input.hasNextLine()) {
lines[j] = input.nextLine();
if(lines[j].length()<dimensionsX){
System.err.println("we are doomed. Input malformed in line j: it has less then" + dimensionsX + "characters");
System.exit(1);
}
maze2[j] = lines[j].toCharArray();
System.out.println(lines[j]);
//System.out.println(j);
}else{
System.err.println("we are doomed. Input has too few lines");
System.exit(1);
}
}
//taken as is, but makes me wonder if it is intended to have dimensionsX as the Y coordinate but well...
for (int i = dimensionsX; i > 0; --i) {
for (int j = dimensionsY; j > 0; --j) {
System.out.print(maze2[j-1][i-1]);
}
System.out.println();
}
Of course you want to do something different than exiting the program if the input is malformed e.g. throw an exception, or do nothing at all if your input is always correct(well is it?).

ArrayIndexOutOfBoundsException when trying to reverse an array

This seems simple enough but I get the error "Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at reverse.main(reverse.java:28)"
I initially take inputs from the user to write an array, and then I want to print the array backwards. I understand there are other ways of doing this, but I mainly want to know why this is not working. Going through it line by line makes sense?
PS. If it's not a problem, is there any better way of doing this?
import java.util.Scanner;
public class reverse {
/**
* #param args
*/
public static void main(String[] args) {
System.out.printf("Enter the number of values in array: ");
Scanner scanner = new Scanner(System.in);
int n;
n = scanner.nextInt();
double[] a1 = new double[n];
int i;
System.out.printf("Enter the value in the array: ");
for (i = 0; i < n; i++){
Scanner scanner2 = new Scanner(System.in);
a1[i] = scanner2.nextInt();
}
double j;
double k;
for (i = 0; i < n/2; i++){
j = a1[i];
k = a1[n-i]; //error line;
a1[i]=k;
a1[n-i]=j;
}
for(i = 0; i < n; i++){
System.out.println(" "+a1[i]);
}}
}
When i = 0, n-i will result in n, which is one larger than the available indexes( 0 -> n-1 ).
for (i = 0; i < n/2; i++){
j = a1[i];
k = a1[n-i]; //error line;
a1[i]=k;
a1[n-i]=j;
}
Collections.reverse(Arrays.asList(array))
Will reverse an array for you, then just print its values out. It's great to do these kinds of problems as exercises but if you're ever woring in the industry it's usually better to rely on the Java API for trivial things like this. Probably going to be faster and a lot more simpler than anything you can come up with.
As said by Samhain, when i = 0, then n-i == n, which is greater than the last index of the array (since arrays start with index 0).
The simplest solution is to just subtract an additional 1 from n-i.
j = a1[i];
k = a1[n-i-1];
a1[i]=k;
a1[n-i-1]=j;
Also, creating a new Scanner is totally unnecessary. Just continue to use the first one you created.
for (i = 0; i < n; i++){
a1[i] = scanner.nextInt();
}
Finally, for what it's worth, if you're using nextInt you don't need to declare your array as a double[] (nor do j and k need to be doubles). You can just use ints.
Here's it running on ideone.

how to print a number triangle in java

I need to produce a triangle as shown:
1
22
333
4444
55555
and my code is:
int i, j;
for(i = 1; i <= 5; i++)
{
for(j = 1; j <= i; j++)  
{          
System.out.print(i); 
}      
System.out.print("\n");        
}
Producing a triangle the opposite way
1
22
333
4444
55555
What do i need to do to my code to make it face the right way?
You need 3 for loops:
Upper-level loop for the actual number to be repeated and printed
first inner level for printing the spaces
second inner level for to print the number repeatedly
at the end of the Upper-level loop print new line
Code:
public void printReversedTriangle(int num)
{
for(int i=0; i<=num; i++)
{
for(int j=num-i; j>0; j--)
{
System.out.print(" ");
}
for(int z=0; z<i; z++)
{
System.out.print(i);
}
System.out.println();
}
}
Output:
1
22
333
4444
55555
666666
I came across this problem in my AP CS class. I think you may be starting to learn how to program so heres what I'd do without giving you the answer.
Use a loop which removes the number of spaces each iteration. The first time through you would want to print four spaces then print 1 one time(probably done in a separate loop).
Next time through one less space, but print i one more time.
You need to print some spaces. There is a relation between the number of spaces you need and the number (i) you're printing. You can print X number of spaces using :
for (int k = 0; k < numSpaces; k++)
{
System.out.print(" ");
}
So in your code:
int i, j;
for(i = 1; i <= 5; i++)
{
// Determine number of spaces needed
// print spaces
for(j = 1; j <= i; j++)
{
System.out.print(i);
}
System.out.print("\n");
}
use this code ,
int i, j,z;
boolean repeat = false;
for (i = 1; i <= 5; i++) {
repeat = true;
for (j = 1; j <= i; j++) {
if(repeat){
z = i;
repeat = false;
while(z<5){
System.out.print(" ");
z++;
}
}
System.out.print(i);
}
{
System.out.print("\n");
}
}
You can use this:
int i, j;
int size = 5;
for (i = 1; i <= size; i++) {
if (i < size) System.out.printf("%"+(size-i)+"s", " ");
for (j = 1; j <= i; j++) {
System.out.print(i);
}
System.out.print("\n");
}
This line:
if (i < size) System.out.printf("%"+(size-i)+"s", " ");
Is going to print the left spaces.
It uses the old printf with a fixed sized string like 5 characters: %5s
Try it here: http://ideone.com/jAQk67
i'm having trouble sometimes as well when it's about formatting on console...
...i usually extract that problem into a separate method...
all about how to create the numbers and spacing has been posted already, so this might be overkill ^^
/**
* creates a String of the inputted number with leading spaces
* #param number the number to be formatted
* #param length the length of the returned string
* #return a String of the number with the size length
*/
static String formatNumber(int number, int length){
String numberFormatted = ""+number; //start with the number
do{
numberFormatted = " "+numberFormatted; //add spaces in front of
}while(numberFormatted.length()<length); //until it reaches desired length
return formattedNumber;
}
that example can be easily modified to be used even for Strings or whatever ^^
Use three loops and it will produce your required output:
for (int i=1;i<6 ;i++ )
{
for(int j=5;j>i;j--)
{
System.out.print(" ");
}
for(int k=0;k<i;k++)
{
System.out.print(i);
}
System.out.print("\n");
}
Your code does not produce the opposite, because the opposite would mean that you have spaces but on the right side. The right side of your output is simply empty, making you think you have the opposite. You need to include spaces in order to form the shape you want.
Try this:
public class Test{
public static void main (String [] args){
for(int line = 1; line <= 5; line++){
//i decreases with every loop since number of spaces
//is decreasing
for(int i =-1*line +5; i>=1; i--){
System.out.print(" ");
}
//j increases with every loop since number of numbers
//is decreasing
for(int j = 1; j <= line; j++){
System.out.print(line);
}
//End of loop, start a new line
System.out.println();
}
}
}
You approached the problem correctly, by starting with the number of lines. Next you have to make a relation between the number of lines (the first for loop) and the for loops inside. When you want to do that remember this formula:
Rate of change*line + X = number of elements on line
You calculate rate of change by seeing how the number of elements change after each line. For example on the first line you have 4 spaces, on the second line you have 3 spaces. You do 3 - 4 = -1, in other words with each line you move to, the number of spaces is decreasing by 1. Now pick a line, let's say second line. By using the formula you will have
-1(rate of change) * 2(line) + X = 3(how many spaces you have on the line you picked).
You get X = 5, and there you go you have your formula which you can use in your code as you can see on line 4 in the for loop.
for(int i = -1 * line +5; i >= 1; i--)
You do the same for the amount of numbers on each line, but since rate of change is 1 i.e with every line the amount of numbers is increasing by 1, X will be 0 since the number of elements is equal to the line number.
for(int j = 1; j <= line; j++){

How to input the second line

The file that is begin read from is
11 -5 -4 -3 -2 -1 6 7 8 9 10 11
8 -33 -22 -11 44 55 66 77 88
11 and 8, the first integer, begin the size of said array. The resulted output, suppose to be an array, is suppose to be two different array base on their first integer size.
I can read and implement the first line of integer using the following code
public class sortList{
public static void main(String args[]){
try{
Scanner s = new Scanner(new File("data"));
int[] array = new int[s.nextInt()];
for (int i = 0; i < array.length; i++){
if (i == 0){
continue;
}
array[i] = s.nextInt();
System.out.println(array[i]);
}
}
catch(IOException e){
e.printStackTrace();
}
}
}
Now how do I read the second line of integer, cause i searched everywhere here. No avail
You're literally halfway there. You've got one loop to go over the first line. After the first loop has completed, you've effectively exhausted the entire line of text.
What you can do is then advance the scanner to the next line by use of the Scanner#nextLine() method.
Then, you create another array to store your second line of text similar to the way you created the first. You don't need to duplicate your Scanner.
In actuality, you could write it as a separate, concise method, and only call it when you're ready to populate your arrays. Outside of the method (after you call it, that is), you'd advance your scanner to the next line.
public int[] readLine(Scanner fileReader) {
int[] array = new int[fileReader.nextInt()];
for (int i = 0; i < array.length; i++){
array[i] = fileReader.nextInt();
}
return array;
}
public class sortList{
public static void main(String args[]){
try{
Scanner s = new Scanner(new File("data.txt"));
int[] array = new int[s.nextInt()];
for (int i = 0; i < array.length; i++){
array[i] = s.nextInt();
System.out.println(array[i]);
}
s.nextLine();
int[] array1 = new int[s.nextInt()];
for (int i = 0; i < array1.length; i++){
array1[i] = s.nextInt();
System.out.println(array1[i]);
}
}
catch(IOException e){
e.printStackTrace();
}
}
First, remove these three lines:
if (i == 0) {
continue;
}
Then, put a while (s.hasNextInt()) { … } (or so, I didn't look up the documentstion) around the int[] array and the } of the for loop.
To see whether it all works, you should then add System.out.println("one record: " + Arrays.toString(array)); as the last line of the while loop.

Categories

Resources