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 :)
Related
I have a program that takes in a file list of bands and albums. I need to determine the number of album each band makes and then print out a list of the the bands and the number of albums they made in descending order. I have looked around and seen it done using mapping and collections. I want to know how to do it without either. Here is what I have so far:
public static void processFile(String filename)
{
String bandname = "";
String[][] data = read_spreadsheet(filename);
//takes the file and converts it to a 2d array
ArrayList<String> bands = new ArrayList<String>();
for(int rows = 0; rows < data.length; rows++)
{
bands.add(data[rows][0]);
}
for(int i = 0; i<bands.size()-1;i++)
{
int albumcount = 0;
for(int j = i+1; j<bands.size();j++)
{
if(bands.get(i).equals(bands.get(j)))
{
albumcount++;
}
}
}
}
input example:
band1 -album
band2 -album
band1 -album
band3 -album
band1 -album
band2 -album
output example:
band1: 3
band2: 2
band3: 1
Without collections? You want to use arrays?
String [] names = new String[data.length];
int [] counts = new int[data.length];
int j = 0;
for (int i = 0; i < data.lenght; i++ ) {
while (j < data.length) {
if (data[i][0].equals(names[j])) {
found = true;
counts[j]++;
break;
} else if (names[j] == null) {
names[j] = data[i][0];
counts[j]=1;
break;
}
j++;
}
}
// find max count
// println
// nullify element
// repeat
for (int i = 0; i < j; i++) {
int max = -1;
int k = i;
int pos = -1;
while ( k < j ) {
if ( counts[k] > max ) {
pos = k;
max = counts[k];
}
k++;
}
if ( pos != -1 ) { // we found
System.out.println ( names[pos] + ": " + counts[pos]);
counts[pos] = -1;
}
}
If you sort the list of band names (with duplicates) and then count how many of each band name is in the list, you will get the album count for each band:
public static void processFile(String filename)
{
//takes the file and converts it to a 2d array
String[][] data = read_spreadsheet(filename);
// get all the bands (with duplicates)
ArrayList<String> bands = new ArrayList<String>();
for(int rows = 0; rows < data.length; rows++) {
bands.add(data[rows][0]);
}
// sort the bands alphabetically
Collections.sort(bands);
int albumCount = 1;
String currentBand = bands.remove(0);
while(bands.size() > 0) {
String nextBand = bands.remove(0);
if(currentBand.equals(nextBand)) {
albumCount++;
} else {
// print the current band album count and setup for the next band
System.out.println(currentBand + ": " + albumCount);
currentBand = nextBand;
albumCount = 1;
}
};
// print the final band album count
System.out.println(currentBand + ": " + albumCount);
}
My code needs to read information from the textfile. And the textfile looks like this:
X...................
....................
....................
....................
....................
....................
....................
....................
....................
..X.................
Yes, I need to get # of rows and columns and also identify the number and location of 'X's. I'm almost done except my second constructor is giving me a StringOutOfBoundException in the line:
treasureLocations[location] = new Coord(i, j);
I need help only with the second constructor. Could smb please help me with that?
import java.util.Scanner; // Required to get input
import java.io.File; // Required to get input from files
// A 2D treasure map which stores locations of treasures in an array
// of coordinates
public class TreasureMap{
int rows, cols; // How big is the treasure map
Coord [] treasureLocations; // The locations of treasures
Scanner kbd = new Scanner(System.in);
// Prompt the user for info on the treasure map and then create it
// COMPLETE THIS METHOD
public TreasureMap(){
int numberOfTreasures = 0;
System.out.println("Enter map size (2 ints): ");
rows = kbd.nextInt(); cols = kbd.nextInt();
System.out.println("Enter number of treasures (1 int): ");
numberOfTreasures = kbd.nextInt();
treasureLocations = new Coord[numberOfTreasures];
for (int i = 0; i < numberOfTreasures; i++)
{
System.out.println("Enter treasure " + i + " location (2 ints): ");
rows = kbd.nextInt(); cols = kbd.nextInt();
treasureLocations[i] = new Coord(rows, cols);
}
}
// Read the string representation of a map from a file
// COMPLETE THIS METHOD
public TreasureMap(String fileName) throws Exception{
rows = 0;
cols = 0;
int treasures = 0;
char x = 'X';
Scanner data = new Scanner(new File(fileName));
while(data.hasNextLine())
{
String line = data.nextLine();
for (int i = 0; i < line.length(); i++)
{
if(x == line.charAt(i))
{
treasures++;
}
}
cols = line.length();
rows++;
}
int location = 0;
treasureLocations = new Coord[treasures];
Scanner temp = new Scanner (new File(fileName));
while(temp.hasNextLine())
{
String line = temp.nextLine();
for(int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
if(x == line.charAt(j))
{
treasureLocations[location] = new Coord(i, j);
location++;
}
}
}
}
}
// true if there is treasure at the given (r,c) coordinates, false
// otherwise
// This method does not require modification
public boolean treasureAt(int r, int c){
for(int i=0; i<treasureLocations.length; i++){
Coord coord = treasureLocations[i];
if(coord.row == r && coord.col == c){
return true;
}
}
return false;
}
// Create a string representation of the treasure map
// This method does not require modification
public String toString(){
String [][] map = new String[this.rows][this.cols];
for(int i=0; i<rows; i++){
for(int j=0; j<cols; j++){
map[i][j] = ".";
}
}
for(int i=0; i<treasureLocations.length; i++){
Coord c = treasureLocations[i];
map[c.row][c.col] = "X";
}
StringBuilder sb = new StringBuilder();
for(int i=0; i<rows; i++){
for(int j=0; j<cols; j++){
sb.append(map[i][j]);
}
sb.append("\n");
}
return sb.toString();
}
}
You should not use the for i as you do. Your i means the current row, doesn't it? So every time you input a line(temp.nextLine()), your i must be added one.
int i=0;
while(temp.hasNextLine())
{
String line = temp.nextLine();
for (int j = 0; j < cols; j++)
{
if(x == line.charAt(j))
{
treasureLocations[location] = new Coord(i, j);
location++;
}
}
}
++i;
}
I'm writing a method that checks to see if the text file being passed into the constructor of my instantiable class contains non-numeric data. Specifically, it matters if the data cannot be represented as a double. That is, chars are not okay, and integers are.
What I have so far is:
private boolean nonNumeric(double[][] grid) throws Exception {
boolean isNonNumeric = false;
for (int i = 0; i < grid.length; i++)
for (int j = 0; j < grid[i].length; j++) {
if (grid[i][j] != ) {
isNonNumeric = true;
throw new ParseException(null, 0);
} else {
isNonNumeric = false;
}
}
return isNonNumeric;
}
I cannot seem to find what I should be checking the current index of grid[i][j] against. As I understand it, typeOf only works on objects.
Any thoughts? Thank you.
Edit: Here is the code used to create the double[][] grid:
// Create a 2D array with the numbers found from first line of text
// file.
grid = new double[(int) row][(int) col]; // Casting to integers since
// the dimensions of the
// grid must be whole
// numbers.
// Use nested for loops to populate the 2D array
for (int i = 0; i < row; i++)
for (int j = 0; j < col; j++) {
if (scan.hasNext()) {
grid[i][j] = scan.nextDouble();
count++;
}
}
// Check and see if the rows and columns multiply to total values
if (row * col != count) {
throw new DataFormatException();
}
I come up with this sample for you, hope it helps.
It helps you to narrow down your entries types to any type that you are looking for.
My entry.txt include :
. ... 1.7 i am book 1.1 2.21 2 3222 2.9999 yellow 1-1 izak. izak, izak? .. -1.9
My code:
public class ReadingJustDouble {
public static void main(String[] args) {
File f = new File("C:\\Users\\Izak\\Documents\\NetBeansProjects"
+ "\\ReadingJustString\\src\\readingjuststring\\entry.txt");
try (Scanner input = new Scanner(f);) {
while (input.hasNext()) {
String s = input.next();
if (isDouble(s) && s.contains(".")) {
System.out.println(Double.parseDouble(s));
} else {
}
}
} catch (Exception e) {
}
}
public static boolean isDouble(String str) {
double d = 0.0;
try {
d = Double.parseDouble(str);
return true;
} catch (NumberFormatException nfe) {
return false;
}
}
}
Output:
1.7
1.1
2.21
2.9999
-1.9
Note: my sources are as follows
1.http://www.tutorialspoint.com/java/lang/string_contains.htm
2.How to check if a String is numeric in Java
I am trying to use the setCharAt method in a StringBuilder but I am getting a null pointer exception. Is there a way I can add values to the StringBuilder array I have made so I wont get these error.
From research I have found the .append() method but I'm not even sure how it works.
import java.util.*; // Allows for the input of a scanner method.
import java.io.*; // Allows for the inputting and outputting of a data file.
import java.lang.*; // Allows for the use of String Methods.
//////////////////////////////////////////////////////////////////////////////////////
public class TESTY
{
static Scanner testanswers;
static PrintWriter testresults;
public static void main(String[] args) throws IOException
{
testanswers = new Scanner(new FileReader("TestInput.dat"));
testresults = new PrintWriter("TestOutput.dat");
String StudentID;
String answers;
// Reads first two lines first to know how many records there are.
String answerKey = testanswers.nextLine();
int count = Integer.parseInt(testanswers.nextLine());
// Allocate the array for the size needed.
String[][] answerArray = new String[count][];
for (int i = 0; i < count; i++)
{
String line = testanswers.nextLine();
answerArray[i] = line.split(" ", 2);
}
for(int row = 0; row < answerArray.length; row++)
{
for(int col = 0; col < answerArray[row].length; col++)
{
System.out.print(answerArray[row][col] + " ");
}
System.out.println();
}
gradeData(answerArray, answerKey);
testanswers.close();
testresults.close();
}
///////////////////////////////////////////////////////////
//Method: gradeData
//Description: This method will grade testanswers showing
//what was missed, skipped, letter grade, and percentage.
///////////////////////////////////////////////////////////
public static double gradeData(String[][] answerArray, String answerKey)
{
String key = answerKey;
double Points = 0;
StringBuilder[] wrongAnswers = new StringBuilder[5];
String studAnswers;
for(int rowIndex = 0; rowIndex < answerArray.length; rowIndex++) /// Counting rows
{
studAnswers = answerArray[rowIndex][1].replace(" ", "S"); ///Counts rows, Col stay static index 1
for(int charIndex = 0; charIndex < studAnswers.length(); charIndex++)
{
if(studAnswers.charAt(charIndex) == key.charAt(charIndex))
{
Points += 2;
}
else if(studAnswers.charAt(charIndex) == 'S')
{
Points --;
}
else if(studAnswers.charAt(charIndex) != key.charAt(charIndex))
{
for(int i = 0; i < wrongAnswers.length; i++)
{
wrongAnswers[i].setCharAt(charIndex, 'X');
}
Points -= 2;
}
}
System.out.println(Points);
}
return Points;
}
}
The error is occurring on line 91 :
wrongAnswers[i].setCharAt(charIndex, 'X');
You have declared an array of StringBuilders, but you haven't initialized any of the slots, so they're still null.
Initialize them:
StringBuilder[] wrongAnswers = new StringBuilder[5];
for (int i = 0; i < wrongAnswers.length; i++)
{
wrongAnswers[i] = new StringBuilder();
}
Additionally, using setCharAt won't work here, because initially, there is nothing in the StringBuilder. Depending on what you want here, you may need to just call append, or you may initially want a string full of spaces so that you can set a specific character to 'X'.
StringBuilder[] wrongAnswers = new StringBuilder[5];
does not create 5 empty StringBuilders but 5 null StringBuilders.
You need to call something like
wrongAnswers[i] = new StringBuilder()
in order to initialize your 5 array members.
Your problem is that
StringBuilder[] wrongAnswers = new StringBuilder[5];
does not create 5 StringBuilder objects. It only creates an array with 5 null StringBuilder references. You need to create each StringBuilder separately with a line such as
wrongAnswers[i] = new StringBuilder();
inside a loop over i.
I have 1,000 lines of data in a text file and I would like each line to be its own float [].
1,1,1,1,1,1
2,2,2,2,2,2
3,3,3,3,3,3
Would result in:
float[0] = {1,1,1,1,1,1}
float[1] = {2,2,2,2,2,2}
float[2] = {3,3,3,3,3,3}
Is this possible? I could only find examples of loading an entire file into an array. I tried hardcoding all the arrays, but exceeded the byte character limit of ~65,000
Try the following:
// this list will store all the created arrays
List<float[]> arrays = new ArrayList<float[]>();
// use a BufferedReader to get the handy readLine() function
BufferedReader reader = new BufferedReader(new FileReader("myfile.txt"));
// this reads in all the lines. If you only want the first thousand, just
// replace these loop conditions with a regular counter variable
for (String line = reader.readLine(); line != null; line = reader.readLine()) {
String[] floatStrings = line.split(",");
float[] floats = new float[floatStrings.length];
for (int i = 0; i < floats.length; ++i) {
floats[i] = Float.parseFloat(floatStrings[i]);
}
arrays.add(floats);
}
Note that I haven't added any exception handling (readLine(), for example, throws IOException).
use a LineIterator to read each line without loading the whole file
for each line, use a regular expression to extract figures like (\d\.)+ and iterator over the matches found with methods like find() and group()
<body>
<pre>
import java.io.FileReader;
public class Check {
public static void main(String[] args) {
readingfile();
}
public static void readingfile() {
try {
FileReader read = new FileReader("D:\\JavaWkspace\\numbers.txt");
int index;
String nums1 = "";
while ((index = read.read()) != -1) {
if (((char) index) != '\n') {
nums1 += String.valueOf((char) index);
}
}
System.out.println("Problem statement: Print out the greatest number on each line:\n" + nums1);
String f = nums1.substring(0, 14);
String s = nums1.substring(15, 29);
String t = nums1.substring(30);
String[] fs = f.split(",");
int size = fs.length;
int[] arr = new int[size];
for (int i = 0; i < size; i++) {
arr[i] = Integer.parseInt(fs[i]);
}
int max = arr[0];
for (int i = 0; i < arr.length; i++) {
if (max < arr[i]) {
max = arr[i];
}
}
System.out.println("\nGreatest number in the first line is:" + (max));
String[] sstr = s.split(",");
int size2 = sstr.length;
int[] arr2 = new int[size2];
for (int i = 0; i < size2; i++) {
arr2[i] = Integer.parseInt(sstr[i]);
}
int max2 = arr2[0];
for (int i = 0; i < arr2.length; i++) {
if (max2 < arr2[i]) {
max2 = arr2[i];
}
}
System.out.println("\nGreatest number in the second line is:" + (max2));
String[] str3 = t.split(",");
int size3 = str3.length;
int[] arr3 = new int[size3];
for (int i = 0; i < size3; i++) {
arr3[i] = Integer.parseInt(str3[i]);
}
int max3 = arr3[0];
for (int i = 0; i < arr3.length; i++) {
if (max3 < arr3[i]) {
max3 = arr3[i];
}
}
System.out.println("\nGreatest number in the third line is:" + (max3));
read.close();
} catch (Exception e) {
System.out.println(e);
}
}
}
</pre>
</body>
Loop over the line-delimited contents of the file with .split("\n") and then cast each result as float array. Here's how to convert the string into a float for you => http://www.devdaily.com/java/edu/qanda/pjqa00013.shtml