Having trouble parsing multiple files and storing in array in Java - arrays

I'm attempting to create a class that takes a certain number of ppm files that are formatted identically (which are input by the user in the class containing the main method), and then compares the corresponding integers in each file one by one, storing them in a temporary array so that they can be sorted and the median can be taken and written to a new ppm file ultimately creating a new image.
For example, if I had 3 files I would want to take the first integer value (after the 3 lines of the header) of each one, storing each value in the temporary array (in this case of size 3) for comparison and then I would want to do the same thing with the second value in each file, and the third, etc. This is what I'm stuck on. Right now the way that I have it set up is leading to a null pointer exception but I've tried various other things that have ran but led to the incorrect result. Any advice?
import java.io.File;
import java.io.IOException;
//import java.io.PrintWriter;
import java.util.Scanner;
import java.util.Arrays;
public class Effects {
public Effects() throws IOException{}
public void filter(File[] files, String outputFileName) throws IOException {
//Create an array of Scanners equal to the number of files
Scanner[] scanner = new Scanner[files.length];
//Create a scanner that is linked to each file that must be read
for(int i=0; i<scanner.length; i++) {
Scanner scan = new Scanner(files[i]);
scanner[i]=scan;
//For each scanner, first skip the first 3 lines of text, then take one integer from
//file and store it in the temporary array compare [such that the integer parsed
// by scanner[0] is stored at compare[0] and so on.
while(scan.hasNext()) {
int [] compare = new int [scanner.length-1];
boolean header = true;
for(int j=0; j<files.length; j++) {
while(header==true) {
//the first 3 lines in each document need to be skipped before the integer values of relevance begin.
scanner[j].nextLine();
scanner[j].nextLine();
scanner[j].nextLine();
header = false;
}
int value = scanner[j].nextInt(); //NULL POINTER EXCEPTION
compare[j] = value;
}
}
}
}
}

The reason you're seeing the NPE is that the j=1 code runs before i=1 and therefore scanner[1] doesn't exist yet.
It might be a good idea to handle reading each file separately and combining the values later. That would also split your reading code from your calculations, making it easier to track down any future bugs.

Related

Can I set an array length with a variable in Java?

I'm trying to establish a string array to hold the names of golfers in a scorecard application. I am asking for user input to get the number of players, and I would like to use that value to define the length of the array. I have a variable to hold the value entered called NUM_PLAYERS, and I am having a problem getting it to define my array length. String[ ] players = new String[NUM_PLAYERS]; When I get to my players entry loop I get the out of bounds exception as soon as I get past the first entry, because the array is only one element long. Here is the ScoreCalc class and my run program as they stand so far:
ScoreCalc class
GameChicago program
my suggestion is to move the initialise of the array to the constructor like this
public class ScoreCalc {
private String[] players;
public ScoreCalc(int playersNum){
this.players = new String[playersNum];
}
...
}
and to create the class after you get the user's input, like this
input = ...
ScoreCalc game = new ScoreCalc(input)
you have some loop there of variables definition with the NUM_PLAYERS

Iterate through multi map in Java

I have a multimap in where my key is a String and the values are Integers. I would like to iterate through all those Integers, in order to calculate the mean value of them, for finally, just store the key and the mean value.
This is what I have written at the moment
int visits = 0;
for (String key : result.keys()) {
Object[] val = result.get(key).toArray();
for (int i=0; i<val.length; i++){
visits+=(Integer)val[i];
}
visits=visits/val.length;
result.removeAll(key);
result.put(key, visits);
}
But I'm getting this error
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
at java.util.AbstractList$Itr.next(AbstractList.java:343)
at com.google.common.collect.AbstractMapBasedMultimap$Itr.next(AbstractMapBasedMultimap.java:1150)
at com.google.common.collect.TransformedIterator.next(TransformedIterator.java:48)
at subset.calcMax.meanCalc(calcMax.java:147)
at subset.calcMax.main(calcMax.java:208)
it points to the line for (String key : result.keys()) but the error is not in this iteration, because if I delete what is in the for loop it works. So my problem is in the iteration through the values that are for each key.
I would appreciate your help.
Thanks in advance!
As explained in the comments, collections throw ConcurrentModificationExceptions when modified while being iterated. It's bad practice to mutate the source collection anyway, so you're better off creating a new collection and returning that.
I would write:
ImmutableMultimap<String, Integer> computeMeanVisits(Multimap<String, Integer> multimap) {
ImmutableMultimap.Builder<String, Integer> result = ImmutableMultimap.builder();
for (String key : multimap.keySet()) {
Collection<Integer> values = multimap.get(key);
result.put(key, mean(values));
}
return result.build();
}
int mean(Collection<Integer> values) {
int sum = 0;
for (Integer value : values) {
sum += value;
}
return sum / values.size();
}
As an aside:
I don't like your use of .toArray() to iterate on the values. In Java, it's usually preferred to manipulate collections directly. Direct Array manipulations should be reserved for very specific, high performance code, or when you have to deal with bad APIs that only accept arrays. Note that in your example, using .toArray() also makes you lose genericity, forcing you to cast each value to an Integer.
you should use the .keySet() method instead of the keys() method, which returns a Multiset. When iterating over this Multiset, keys associated with multiple values will appear multiple times.
your "visits" variable is not reset to 0 before computing a new mean

How to use scanner to input into a 2 dimensional array?

I'm taking a online Java course and attempting my 2nd assignment. The first assignment was not difficult but this one is just way over top. I honestly don't know where to begin. The problem is this class is online, basic instructions are to read these chapters and then write the program. There's not much guidance since my instructor is not with me physically.
I've never used scanner before or created two dimensional arrays. My instructor gives notes on what to do in each area of his skeleton program but I don't have a clue which one to start with.
Your task is to implement a similar scheme to store poynomials of any number of terms, such that the
number of terms and the components (coefficient, variable and exponent) of every term are entered from
the keyboard.
To implement the interactive input we will using the Java class Scanner, defined in the java.utils
standard package. The Scanner class can be used in Java to read data types from a file. Since the input
console (keyboard) is treated as the file called System.in, we can create a Scanner for that input stream
as new Scanner (System.in), as shown below. Once you define a Scanner object, using its method
next() you can read Strings from the file/keyboard.
The incomplete program below is your assignment. You are supposed to complete without changing the
existing code.
Your output should be the terms of the polynomial entered by the user, separated by + signs.
Additional instructions in the code below, that you will change to achieve the requested functionality.
import java.util.Scanner;
public class Polynomials {
public static void storeTerm (int coeff, String var, int exp, String poly[][], int
where){
//ENTER THE COEFFICIENT, VARIABLE AND EXPONENT INTO THE
//ARRAY POLY THAT REPRESENTS THE POLYNOMIAL, AT POSITION "where"
//THAT RANGES BETWEEN INDEX 0 AND POLY.LENGTH-1
}
public static void printTerm (String [] term) {
//PRINTS EACH TERM
//IF THE EXPONENT OF THE VARIABLE IS 1 DOE NOT PRINT THE EXPONENT
//IF THE EXPONENT IS 0, PRINT ONLY THE COEFFCIENT
//IF THE COEFFICIENT IS 1, DO NOT PRINT IT, UNLESS IT IS THE ONLY COMPONENT OF
//THE TERM
}
public static void printPolynomial(String terms[][]){
//CALL printTerm in a loop to print all terms separated by + signs
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int numberTerms = 0;
System.out.println("How many terms?");
numberTerms = sc.nextInt();
//ENTER HERE THE CODE TO CREATE THE TWO DIMENSIONAL ARRAY NEEDED TO STORE THE TERMS
//OF THE POLYNOMIAL
if (numberTerms <= 0)
System.out.println("Error: Polynomials must have at least one term");
else {
String coeff = "", variable="", exponent="";
for (int i = 1; i<= numberTerms; i++) {
System.out.println("Enter the coeffcient for term " + i);
coeff = sc.next();
System.out.println("Enter the variable name:");
variable = sc.next();
System.out.println("Enter the expoenent for this term");
exponent = sc.next();
//CALL METHOD storeTerm TO INPUT THIS NEW TERM INTO THE ARRAY WRITE THE CORRECT
//CALL TO storeTerm HERE
}
printPolynomial(terms);
}//endf if
}//end main
}//end class
Again not looking for answers. Just where to start. Then I'll post my results.
It is not completely obvious where the two-dimensional array enters, since the structure hints at a list of terms.
You will need to define a data structure, in Java as a class, to hold the information for each term.
From the description, it seems that the input are polynomials of the form 3x^2+5y^7 and not xy+3y^2z^3.

How do i keep my program going?

Hey guys im making a game to help me study for finals. It is basically flash cards. I want the program to print out my question and answer by randomly selecting one. The thing is i dont want he same random number to be picked twice. how do i make sure the same number isn't picked twice till im out of questions? I am trying to make each random number be stored in blacklist so i can just check if the number is already in there before the program prints.
import java.util.ArrayList;
import java.util.Random;
public class Games {
static ArrayList<Integer> blacklist = new ArrayList<Integer>();
static int number;
static String[][] yes = {{"Apostolic Orgin", "Comes form the apostles"},
{"Biblical inerrancy", "the doctrine that the books are free from error reading the truth"},
{"Divine Inspiration", "the assistance the holy spirit gave the authors or the bible so they could write"},
{"fundamentalist approach", "interpretation of the bible and christian doctrine based on the literal meaning og bible's word"}, {"pentateuch", "first 5 books of old testament"}};
public static void main(String[] args) {
Printer(pickQuestion(), pickAnswer());
}
public static int RandomNumber(int i) {
int c;
Random r = new Random();
c = r.nextInt(i);
return c;
}
public static void Printer(String question, String answer) {
System.out.println("Question: " + question);
System.out.println("Answer: " + answer);
}
public static String pickQuestion() {
number = RandomNumber(yes.length);
return yes[number][0];
}
public static String pickAnswer() {
return yes[number][1];
}
}
The easiest option is to pre-shuffle the list of questions, either messing with the question and answer arrays directly, or by creating an array of integers from 1 to n where is the number of questions, shuffling that, and then loading the "card" in the position pointed to by that value in the array.
That is, create
[1,2,3,4,5]
Shuffle:
[5,1,3,4,2]
And load question 5, then question 1, etc.
This latter option would make a few things easier, not least of which is debugging!
Creating the array in order is a trivial for loop, and there are plenty of standard algorithms for shuffling too.
Random shuffling of an array

read a file into an array of lines in d

What is the proper way to read a text file into an array of lines? I found the following on Rosetta Stone:
string[] readLines(string filename) {
auto f = File(filename);
scope(exit) f.close();
string[] lines;
foreach (str; f.byLine) {
lines ~= str.idup;
}
return lines;
}
but it looks like it's doing one array resize per line, which is pretty inefficient. I could keep track of the number of lines read in and resize the array via the standard doubling method
int i = 0;
foreach (str; f.byLine) {
if (lines.length <= i + 1) {
lines.length = lines.length * 2 + 1;
}
lines[i] = str.idup;
i++;
}
lines.length = i;
but that's enough boilerplate code that I have to wonder if I'm not just overlooking something in the standard library that already does this for me.
Edit: giving fwend's comment more visibility: this article describes in detail how the array allocator works, and why appending is handled efficiently by the runtime
Actually, D will double the array's reserved space whenever it runs out of room, so you don't need to do it by hand. There is a lot of information about D's arrays here
You probably will get a lot of reallocations initially, but as the array grows, its capacity should grow such that it's less likely to allocate with further appending. You can print out the array's capacity property though to see how it grows.
If you're particularly worried about appending performance, however, then you should probably use std.array.Appender, in which case, your code would look something like this:
string[] readLines(string filename)
{
auto file = File(filename);
auto lines = appender!(string[]);
foreach(line; file.byLine())
lines.put(to!string(line));
return lines.data;
}
Appender is designed to make appending more efficient and will take advantage of whatever tricks it can to make appending more efficient than ~= would be by itself.
Maybe this:
import std.algorithm;
import std.array;
import std.file;
string[] readLines(string input)
{
Appender!(string[]) result;
foreach (line; input.splitter("\n"))
result.put(line);
return result.data;
}
void main()
{
string input = cast(string)std.file.read("test.d");
string[] lines = readLines(input);
}
It should be fast enough since result is just creating slices of the preloaded input string and not allocating new arrays (apart from the allocation of the slices themselves, IOW the pointer+length fields).

Resources