two dimensional array in java - difficulties - java

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.

Related

Finding the largest string in the second column of a 2d array

I have a 2d array and I'm trying to find the largest string only in the second column of the 2d array, but for some reason it only gives me the first string in the 2nd column even if there is a bigger string. Here's what I have:
class Main{
public static void main(String[] args) {
String[][] data = {
{"Jeep", "Wrangler", "35000"},
{"Honda", "civic", "25000"},
{"Toyota", "Corolla", "22000"}
};
LargestName(data);
}
public static void LargestName(String[][] a){
String largestN = a[0][1];
for(int i = 0; i < a.length; i++){
if(largestN.compareTo(a[i][1])<0){
largestN = a[i][1] + "";
}
}
System.out.println(largestN);
}
}
Again, I'm trying to compare the strings only in the second column of the 2d array but with what I have it only gives me the first string of the 2nd column "Wrangler", even if there is a larger string in the 2nd column. Please help
I cannot see a flaw in the code. So look at the definition of 'largest string': It is possible that the code really returns exactly that value that you chose in the beginning.
This can be easily tested by choosing a different start value.
On top of that you could add more System.out.println, or even better use a debugger to step through your code. This will give you a very good understanding of how the JVM executes your code.
You need to comapre length, compareTo is not good choice, please look what are you trying to do:
System.out.println("Wrangler".compareTo("civic"));
System.out.println("civic".compareTo("Corolla"));
System.out.println("Corolla".compareTo("Wrangler"));
result:
-12 32 -20

java split a string and put into an array position

So i am using string.split because i need to take certain parts of a string and then print the first part. The part size may vary so I can't use substring or a math formula. I am attempting to store everything I need in the string array to then selectively print what I need based on the position, this much I can control. However, I am not sure what to do because I know when I do a split, it takes the two parts and stores them in the array. However, there is one case where I need that value in the array untouched. I'm afraid if I do
format[0] = rename
That it will overwrite that value and mess up the entire array. My question is how do I assign a position to this value when I don't know what the position of the others will be? Do I need to preemptively assign it a value or give it the last possible value in the array? I have attached a segment of the code that deals with my question. The only thing I can add is that this is in a bigger loop and rename's value changes every iteration. Don't pay to much attention to the comments, those are more of reminders for me as to what to do rather than what the code is suppose to do. Any pointers, tips, help is greatly appreciated.
String format[];
rename = workbook.getSheet(sheet).getCell(column,row).getContents();
for(int i = 0; i < rename.length(); i++) {
//may need to add[i] so it has somewhere to go and store
if(rename.charAt(i) == '/') {
format = rename.split("/");
}
else if(rename.charAt(i) == '.') {
if(rename.charAt(0) == 0) {
//just put that value in the array
format = rename;
} else {
//round it to the tenths place and then put it into the array
format = rename.split("\\.");
}
} else if(rename.charAt(i) == '%') {
//space between number and percentage
format = rename.split(" ");
}
}
Whenever you assign a variable it gets overwritten
format[0] = rename
Will overwrite the first index of this array of Strings.
In your example, the 'format' array is being overwritten with each iteration of the for loop. After the loop has been completed 'format' will contain only the values for the most recent split.
I would suggest looking into using an ArrayList, they are much easier to manage than a traditional array and you can simply just iterate through the split values and append them at the end.

Searching an Array for a combination of letters and numbers

I'm a first year programmer.
I've been trying to search an array which has stored four variables, with an input.
All of the examples I've found make use of int, and searches for a number within a list.
My program must search for a combination of letters and numbers. (Ex. COP 2800)
import java.util.Scanner;
public class courseInfo {
public static int courseInfo(int[] list, int key) {
Scanner input = new Scanner(System.in);
// Input course name
System.out.print("Enter course name: (Ex. COP 2800) ");
double courseInput = input.nextDouble();
for (int i = 0; i < list.length; i++) {
if (key == list[i])
return i;
}
return -1;
}
public static void main(String[] args) {
int[] list = {COP 2800, PSY 1012, EVR 2001, COP 1000};
System.out.println(linearSearch(list, courseInput));
}
}
Please use layman's terms, I've only been in this class for three weeks.
If I remove COP, PSY, EVR, and COP from line 21, I return a different error;
courseInfo.java:22: error: cannot find symbol
System.out.println(linearSearch(list, courseInput));
^
symbol: variable courseInput
location: class courseInfo
1 error
You are checking an equals condition on String values with a courseInput which is supposed to be an int.
Also, You are returning -1 for whatever happens in the if condition. Are you supposed to return -1 if the value of key doesn't equal the one in the list?
Also the courseInput variable is local to the method. Make it global by declaring it in the class as a member variable.
You have double courseInput = input.nextDouble(), which will only accept doubles, not characters. You also have int[] list, which is an array of integers, so it cannot hold characters either. You'll have better luck if you put the whole course name (both letters and numbers) into a String. Then you can scan an entire line and store it in an array of Strings.
I suggest you do a bit more work on the basic data types of Java before attempting this. Java is a fairly strictly typed language which means that in general (there are plenty of exceptions) you need to decide what type of value you are storing in a variable ahead of time. You are mixing many types in your code: integers, doubles and strings.
So start by deciding if a course's identifier is a number of a name. If it's a number you can use an int to store it. If it's a name you can use a String. You note that a subject includes letters and numbers. But as long as you don't need to compare the numbers directly then you can store the entire identifier in a String. There's no need to split them up.
Another common trap for new starters is that primitive types (such as int) behave quite differently than objects (such as String). An immediate difference is the meaning of ==. For primitive types it compares the values while for objects it checks if the left and right side refer to the same object.
I suspect you want your subjects to be identified by name (i.e. String). In which case your code might look something like:
String[] subjects = {"COP2800", "PSY1012", "EVR2001"};
and
for (int i = 0; i < subjects.length; i++) {
if (subjects[i].equals(name))
return i;
}
return -1;

Fastest way to parse txt file in Java

I have to parse a txt file for a tax calculator that has this form:
Name: Mary Jane
Age: 23
Status: Married
Receipts:
Id: 1
Place: Restaurant
Money Spent: 20
Id: 2
Place: Mall
Money Spent: 30
So, what i have done so far is:
public void read(File file) throws FileNotFoundException{
Scanner scanner = new Scanner(file);
String[] tokens = null;
while(scanner.hasNext()){
String line= scanner.nextLine();
tokens = line.split(":");
String lastToken = tokens[tokens.length - 1];
System.out.println(lastToken);
So, I want to access only the second column of this file (Mary Jane, 23, Married) to a class taxpayer(name, age, status) and the receipts' info to an Arraylist.
I thought of taking the last token and save it to an String array, but I can't do that because I can't save string to string array. Can someone help me? Thank you.
The fastest way, if your data is ASCII and you don't need charset conversion, is to use a BufferedInputStream and do all the parsing yourself -- find the line terminators, parse the numbers. Do NOT use a Reader, or create Strings, or create any objects per line, or use parseInt. Just use byte arrays and look at the bytes. It's a little messier, but pretend you're writing C code, and it will be faster.
Also give some thought to how compact the data structure you're creating is, and whether you can avoid creating an object per line there too by being clever.
Frankly, I think the "fastest" is a red herring. Unless you have millions of these files, it is unlikely that the speed of your code will be relevant.
And in fact, your basic approach to parsing (read line using Scanner, split line using String.split(...) seems pretty sound.
What you are missing is that the structure of your code needs to match the structure of the file. Here's a sketch of how I would do it.
If you are going to ignore the first field of each line, you need a method that:
reads a line, skipping empty lines
splits it, and
returns the second field.
If you are going to check that the first field contains the expected keyword, then modify the method to take a parameter, and check the field. (I'd recommend this version ...)
Then call the above method in the correct pattern; e.g.
call it 3 times to extract the name, age and marital status
call it 1 time to skip the "reciepts" line
use a while loop to call the method 3 times to read the 3 fields for each receipt.
First why do you need to invest time into the fastest possible solution? Is it because the input file is huge? I also do not understand how you want to store result of parsing? Consider new class with all fields you need to extract from file per person.
Few tips:
- Avoid unnecessary per-line memory allocations. line.split(":") in your code is example of this.
- Use buffered input.
- Minimize input/output operations.
If these are not enough for you try to read this article http://nadeausoftware.com/articles/2008/02/java_tip_how_read_files_quickly
Do you really need it to be as fast as possible? In situations like this, it's often fine to create a few objects and do a bit of garbage collection along the way in order to have more maintainable code.
I'd use two regular expressions myself (one for the taxpayer and another for the receipts loop).
My code would look something like:
public class ParsedFile {
private Taxpayer taxpayer;
private List<Receipt> receipts;
// getters and setters etc.
}
public class FileParser {
private static final Pattern TAXPAYER_PATTERN =
// this pattern includes capturing groups in brackets ()
Pattern.compile("Name: (.*?)\\s*Age: (.*?)\\s*Status: (.*?)\\s*Receipts:", Pattern.DOTALL);
public ParsedFile parse(File file) {
BufferedReader reader = new BufferedReader(new FileReader(file)));
String firstChunk = getNextChunk(reader);
Taxpayer taxpayer = parseTaxpayer(firstChunk);
List<Receipt> receipts = new ArrayList<Receipt>();
String chunk;
while ((chunk = getNextChunk(reader)) != null) {
receipts.add(parseReceipt(chunk));
}
return new ParsedFile(taxpayer, receipts);
}
private TaxPayer parseTaxPayer(String chunk) {
Matcher matcher = TAXPAYER_PATTERN.matcher(chunk);
if (!matcher.matches()) {
throw new Exception(chunk + " does not match " + TAXPAYER_PATTERN.pattern());
}
// this is where we use the capturing groups from the regular expression
return new TaxPayer(matcher.group(1), matcher.group(2), ...);
}
private Receipt parseReceipt(String chunk) {
// TODO implement
}
private String getNextChunk(BufferedReader reader) {
// keep reading lines until either a blank line or end of file
// return the chunk as a string
}
}

Change an array of ints to a series of strings

I'm trying to achieve the following output from the following input:
Sample input:
3 4
2 1
4 5
-1
Sample output:
7
3
9
So far, I have my program doing all of the math and I'm getting it to terminate when the user puts in a negative number. My problem is that I'm having trouble getting it to print in the above format. A sample of my input/output is below:
9 9
8 8
9 -8
[18, 16]
Here's my code so far:
import java.util.ArrayList;
import java.util.Scanner;
public class sums{
public static void main(String[]args){
int addition = 0;
int previous = 0;
ArrayList<String> sums = new ArrayList<String>();
String sumsy = new String("");
for (int i=0; i<=i;){
Scanner in = new Scanner(System.in);
previous = in.nextInt();
if (previous<0){
break;
}
else {
addition = in.nextInt();
if (addition<0) {
break;
}
else {
addition += previous;
sums.add(addition+"");
}
}
} System.out.println(sums);
}
}
I believe the answer lies in somehow using a delimiter ("/n") somewhere, and getting my array of ints to print out just as strings.
I'm sorry, these small things elude me completely. Can anyone point me in the right direction?
Thank you!
-Helen
for (String sum : sums) System.out.println(sum)
use this instead of
System.out.println(sums)
System.out is a PrintStream object, and its println methods are overloaded for a variety of different types.
In this case, because sums is an ArrayList, you're calling println(Object x), which works by calling String.valueOf(x) on the passed object (which in turn calls x.toString() if x does not equal null), and printing the resulting String.
Essentially, when you pass something other than a String or a primitive to println, you're delegating the details of how it gets printed to the class of the object. In this case, since ArrayList is a library class, you have no control over this.
To make it work the way you want, you need to iterate over the values in sums, something like:
for (String someSum : sums) {
System.out.println(someSum);
}
If you're not familiar with that loop syntax, see the second half of this page: http://docs.oracle.com/javase/tutorial/java/nutsandbolts/for.html
sums is an list of strings, not a string, so printing it isn't going to give you what you want. You have two options, you could do
for(String i : sums){ System.out.println(i); }
or you could make sums a stringbuilder and do sums.append(addition) and then System.out.println(sums.toString())
Do you really have to use an ArrayList? IMO, this makes it much more complicated than necessary. From your example input, it appears that you simply want to sum each pair of numbers. This doesn't seem to require an array. You could just add the two numbers together and immediately print out the result.

Categories