I'm trying to figure out how to read data from a file, using an array. The data in the file is listed like this:
Clarkson 80000
Seacrest 100000
Dunkleman 75000
...
I want to store that information using an array. Currently I have something like this to read the data and use it:
String name1 = in1.next();
int vote1 = in1.nextInt();
//System.out.println(name1 +" " + vote1);
String name2 = in1.next();
int vote2 = in1.nextInt();
//System.out.println(name2 +" " + vote2);
String name3 = in1.next();
int vote3 = in1.nextInt();
...
//for all names
Problem is, the way I'm doing it means I can never manipulate the file data for more contestants or whatnot.
While I can use this way and handle all the math within different methods and get the expected output...its really inefficient I think.
Output expected:
American Idol Fake Results for 2099
Idol Name Votes Received % of Total Votes
__________________________________________________
Clarkson 80,000 14.4%
Seacrest 100,000 18.0%
Dunkleman 75,000 13.5%
Cowell 110,000 19.7%
Abdul 125,000 22.4%
Jackson 67,000 12.0%
Total Votes 557,000
The winner is Abdul!
I figure reading input file data into arrays is likely easy using java.io.BufferedReader is there a way not to use that?
I looked at this: Java: How to read a text file but I'm stuck thinking this is a different implementation.
I want to try to process all the information through understandable arrays and maybe at least 2-3 methods (in addition to the main method that reads and stores all data for runtime). But say I want to use that data and find percentages and stuff (like the output). Figure out the winner...and maybe even alphabetize the results!
I want to try something and learn how the code works to get a feel of the concept at hand. ;c
int i=0
while (in.hasNextLine()) {
name = in.nextLine();
vote = in.nextInt();
//Do whatever here: print, save name and vote, etc..
//f.e: create an array and save info there. Assuming both name and vote are
//string, create a 2d String array.
array[i][0]=name;
array[i][1]=vote;
//if you want to individually store name and votes, create two arrays.
nameArray[i] = name;
voteArray[i] = vote;
i++;
}
This will loop until he automatically finds you don't have any more lines to read. Inside the loop, you can do anything you want (Print name and votes, etc..). In this case, you save all the values into the array[][].
array[][] will be this:
array[0][0]= Clarkson
array[0][1]= 80,000
array[1][0]= Seacrest
array[1][1]= 100,000
...and so on.
Also, I can see that you have to do some maths. So, if you save it as a String, you should convert it to double this way:
double votesInDouble= Double.parseDouble(array[linePosition][1]);
You have several options:
create a Class to represent your File data, then have an array of those Objects
maintain two arrays in parallel, one of the names and the other of the votes
Use a Map, where the name of the person is the key and the number of votes is the value
a) gives you direct access like an array
b) you don't need to create a class
Option 1:
public class Idol
{
private String name;
private int votes;
public Idol(String name, int votes)
{
// ...
}
}
int index = 0;
Idol[] idols = new Idol[SIZE];
// read from file
String name1 = in1.next();
int vote1 = in1.nextInt();
//create Idol
Idol i = new Idol(name1, vote1);
// insert into array, increment index
idols[index++] = i;
Option 2:
int index = 0;
String[] names = new String[SIZE];
int[] votes = new int[SIZE];
// read from file
String name1 = in1.next();
int vote1 = in1.nextInt();
// insert into arrays
names[index] = name1;
votes[index++] = vote1;
Option 3:
// create Map
Map<String, Integer> idolMap = new HashMap<>();
// read from file
String name1 = in1.next();
int vote1 = in1.nextInt();
// insert into Map
idolMap.put(name1, vote1);
Now you can go back any manipulate the data to your hearts content.
Related
In my task I need to read this input 1,2,3. I read it from file.
String listOfNumbers= reader.readLine();
listOfNumbers= listOfNumbers.replace(",", " ");
for (int i = 0; i< listOfNumbers.length(); i++) {
if (Character.isDigit(listOfNumbers.charAt(i)))
System.out.println(listOfNumbers);
}
Output is always 1 2 3 but I want for every number to send it to function.
E.g.
if (listOfNumbers) =1 then send it to function.
if (listOfNumbers) = 2 ....
I mean if listOfNumber equals some number.
My friend did it with regex but I didn't find right solutio.
you can split the String like so:
val members = listOfNumbers.split(",")
And then you have each individual number separately in the List members and you can pass them as parameters to whatever function you want.
Try to use an array of string with the method Split() is easier to work with
Alright so I'm working on a program that reads a periodic table and you can search elements based on number or abbreviation.
Anyway, I'm a bit stuck trying to read the periodic table file into 4 different arrays: Atomic Number, Abbreviation, Element Name, and Atomic Weight.
I dunno how to write a single method to import all that info into each array in one go. I want to have a class that holds all these arrays and that I can call to later when I need each one.
Here is what I got so far, I'm a bit rusty by the way... I thought working on this program would refamiliarize me with the basics.
class PeriodicTable{
private String fileName = "periodictable.dat";
private int[] atomicNumTable = new int[200];
private String[] abbreviationTable = new String[200];
private String[] nameTable = new String[200];
private double[] atomicWeightTable = new double[200];
PeriodicTable(String fileName){
readTable(fileName);
}
public int[] readTable(String fileName){
Scanner inFile = null;
try{
inFile = new Scanner(new File(fileName));
}catch(FileNotFoundException nf){
System.out.println(fileName + " not found");
System.exit(0);
}
atomicNumTable = new int[200];
int i = 0;
while(inFile.hasNext() && i < atomicNumTable.length){
int number = inFile.nextInt();
atomicNumTable[i] = number;
i++;
}
inFile.close();
return atomicNumTable;
}
}
Here is what each line of the table looks like:
1 H Hydrogen 1.00794
Simply use java.lang.String.split(' ') (assuming that your columns are separated using spaces; if it is using something else; you just need to adapt that regular expression parameter!)
That will return an array of Strings; and you basically now: first column should be an int, then you got two Strings, and then a double value. Or lets be precise: you get strings, that mean something else; thus you have to look into methods like Integer.valueOf(); and similar for Double.
Shouldn't be too hard to work your way from there.
But I recommend some changes to your logic: having 4 different tables doesn't make sense at all. Good OO programming is about creating helpful abstractions. Without abstractions, your program becomes abstract itself.
Meaning: you should introduce a class like
public class Element {
private final int id;
private final String abbreviation;
private final String fullName;
private final double atomicWeight;
... with one constructor that takes all 4 parameters
... with getter methods for the fields of this class
... and meaningful overrides for equals() and hashcode()
}
And then, instead of creating 4 arrays; you create one array, or even better an ArrayList<Element>. And instead of pushing your 4 values into 4 different arrays, you create one new Element object in each loop iteration; and you add that new object to your list.
The major difference to your solution would be: you can deal with Elements as a whole; whereas in your solution, a single "Element" is basically an index that points into 4 different tables.
You can simplify this code a lot. Try something like this.
1) Read the file line by line, split lines as you go,
add values to some ArrayList containing String[]
2) Close your file
3) Turn the ArrayList into a String[][]
4) Print the result
Also, note that arrays in Java are indexed starting at 0 not at 1.
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Arrays;
public class Test {
static public void main(String[] args) throws Exception {
File file = new File("periodictable.dat");
FileReader reader = new FileReader(file);
BufferedReader buffReader = new BufferedReader(reader);
String s = null;
ArrayList<String[]> lst = new ArrayList<String[]>();
String[][] res = null;
while((s = buffReader.readLine()) != null){
String[] arr = s.split("[\\s]+");
lst.add(arr);
}
buffReader.close();
res = new String[lst.size()][lst.get(0).length];
res = lst.toArray(res);
System.out.println();
// System.out.println(res);
// String result = Arrays.deepToString(res);
// System.out.println(result);
System.out.println();
for (int i=0; i<res.length; i++){
for (int j=0; j<res[i].length; j++){
System.out.println("res[" + (i+1) + "][" + (j+1) + "]=" + res[i][j]);
}
}
System.out.println();
}
}
OUTPUT:
res[1][1]=1
res[1][2]=H
res[1][3]=Hydrogen
res[1][4]=1.00794
value iterates indexing for each line
You can distinguish four cases in the loop:
i%4 == 0
i%4 == 1
i%4 == 2
i%4 == 3
Depending on this you know the kind of next value you have to read. So, you can search you an integer, string or floating point number and put the value in the right place.
I support the recommendation of GhostCat to only have one array and a class that contains all four values of a line instead of having four arrays.
I've got some text files I need to extract data from. The file itself contains around a hundred lines and the interesting part for me is:
AA====== test==== ====================================================/
AA normal low max max2 max3 /
AD .45000E+01 .22490E+01 .77550E+01 .90000E+01 .47330E+00 /
Say I need to extract the double values under "normal", "low" and "max". Is there any efficient and not-too-error-prone solution other than regexing the hell out of the text file?
If you really want to avoid regexes, and assuming you'll always have this same basic format, you could do something like:
HashMap<String, Double> map = new HashMap<>();
Scanner scan = new Scanner(filePath); //or your preferred input mechanism
assert (scan.nextLine().startsWith("AA====:); //remove the top line, ensure it is the top line
while (scan.hasNextLine()){
String[] headings = scan.nextLine().split("\\s+"); //("\t") can be used if you're sure the delimiters will always be tabs
String[] vals = scan.nextLine().split("\\s+");
assert headings[0].equals("AA"); //ensure
assert vals[0].equals("AD");
for (int i = 1; i< headings.length; i++){ //start with 1
map.put(headings[i], Double.parseDouble(vals[i]);
}
}
//to make sure a certain value is contained in the map:
assert map.containsKey("normal");
//use it:
double normalValue = map.get("normal");
}
Code is untested as I don't have access to an IDE at the moment. Also, I obviously don't know what's variable and what will remain constant here (read: the "AD", "AA", etc.), but hopefully you get the gist and can modify as needed.
If each line will always have this exact form you can use String.split()
String line; // Fill with one line from the file
String[] cols = line.split(".")
String normal = "."+cols[0]
String low = "."+cols[1]
String max = "."+cols[2]
If you know what index each value will start, you can just do substrings of the row. (The split method technically does a regex).
i.e.
String normal = line.substring(x, y).trim();
String low = line.substring(z, w).trim();
etc.
I've got a question about making a save function.
I'm trying to have a string be saved as a single file to set specific settings on a game. So saveFile would read "002007...", having 002 be a player's location, then 007 a player's level, for example.
I understand how to compile the various variables into a single string, but how would I return it to individual variables?
You better go with SQLite or SharedPreferences if you really want to save settings for a game on Android.
On the other hand, if you have to stick with saving a String on a file, you might want to use a delimiter(ie \r\n or # or | would do it) between numbers. So while parsing back delimiters will help you a lot, but beware when things get complicated a single String won't do the thing nicely. Then you might want to use JSON (for simplicity I would prefer gson) to encode your settings into one String and vice verse.
You could use a delimiter between the values like this:
int location = 02;
int level = 3;
int powerUps = 46;
... and so on
String saveString = location + "#" + level + "#" + powerUps + "#" + ...
Then to load the String back into variables:
String[] values = saveString.split("#");
location = values[0];
level = values[1];
powerUps = values[2];
... and so on
My advice is to check out Shared Preferences and you can read Android's documentation on it here.
If you did want to use your single String, file method, I suggest using delimiters. That simply means to put commas, or other types of delimeters in between different integer values. Instead of "002007", save it as "002,007". Example:
String s = "002,007"
String[] values = s.split(","); // values[0] is "002" and values[1] is "007"
Using the .split(String) command will return a String array with each element in the array containing parts of the String that was split up by the parameter, in this case: ,
If you wanted to separate values per person, something like this could be done:
String s = "002,007;003,008";
String[] people = s.split(";"); // people[0] is "002,007", people[1] is "003,004"
String[][] person = new String[people.length][people[0].split(",").length];
for (int i = 0; i < people.length; i++)
{
person[i] = people[i].split(",");
}
Here is what the array would then contain:
person[0][0] is "002"person[0][1] is "007" person[1][0] is "003" person[1][1] is "008"
// print it for your own testing
for (String ppl[] : person)
{
for (String val : ppl)
{
System.out.print(val + " ");
}
System.out.println("");
}
I'm used to python and django but I've recently started learning java. Since I don't have much time because of work I missed a lot of classes and I'm a bit confused now that I have to do a work.
EDIT
The program is suppose to attribute points according to the time each athlete made in bike and race. I have 4 extra tables for male and female with points and times.
I have to compare then and find the corresponding points for each time (linear interpolation).
So this was my idea to read the file, and use an arrayList
One of the things I'm having difficulties is creating a two dimensional array.
I have a file similar to this one:
12 M 23:56 62:50
36 F 59:30 20:60
Where the first number is an athlete, the second the gender and next time of different races (which needs to be converted into seconds).
Since I can't make an array mixed (int and char), I have to convert the gender to 0 and 1.
so where is what I've done so far:
public static void main(String[] args) throws FileNotFoundException {
Scanner fileTime = new Scanner (new FileReader ("time.txt"));
while (fileTime.hasNext()) {
String value = fileTime.next();
// Modify gender by o and 1, this way I'm able to convert string into integer
if (value.equals("F"))
value = "0";
else if (value.equals("M"))
value = "1";
// Verify which values has :
int index = valor.indexOf(":");
if (index != -1) {
String [] temp = value.split(":");
for (int i=0; i<temp.length; i++) {
// convert string to int
int num = Integer.parseInt(temp[i]);
// I wanted to multiply the first number by 60 to convert into seconds and add the second number to the first
num * 60; // but this way I multiplying everything
}
}
}
I'm aware that there's probably easier ways to do this but honestly I'm a bit confused, any lights are welcome.
Just because an array works well to store the data in one language does not mean it is the best way to store the data in another language.
Instead of trying to make a two dimensional array, you can make a single array (or collection) of a custom class.
public class Athlete {
private int _id;
private boolean _isMale;
private int[] _times;
//...
}
How you intend to use the data may change the way you structure the class. But this is a simple direct representation of the data line you described.
Python is a dynamically-typed language, which means you can think of each row as a tuple, or even as a list/array if you like. The Java idiom is to be stricter in typing. So, rather than having a list of list of elements, your Java program should define a class that represents a the information in each line, and then instantiate and populate objects of that class. In other words, if you want to program in idiomatic Java, this is not a two-dimensional array problem; it's a List<MyClass> problem.
Try reading the file line by line:
while (fileTime.hasNext())
Instead of hasNext use hasNextLine.
Read the next line instead of next token:
String value = fileTime.next();
// can be
String line = fileTime.nextLine();
Split the line into four parts with something as follows:
String[] parts = line.split("\\s+");
Access the parts using parts[0], parts[1], parts[2] and parts[3]. And you already know what's in what. Easily process them.