Way to scan contents of a singular array index? - java

There is an array in my code that includes the names to random items delimited by a /n (i think). the splitLines[] array is an organizational method that collects strings and integers separated by a delimiter in a file. The file is formatted as
<<Prize’s Name 0>>\t<<Prize’s Price 0>>\n
<<Prize’s Name 1>>\t<<Prize’s Price 1>>\n
My goal is to assign each line in the contents of splitLines[0] and splitLines[1] to its own index in separate arrays. The splitLines[0] array is formatted as
<<Prize's Name 0>>/n
<<Prize's Name 1>>/n
and the splitLines[1] array is formatted as
<<Prize's Price 0>>/n
<<Prize's Price 1>>/n
The process here is messy and convoluted, but as I am still learning the inner workings of arrays (and java as a language), I have yet to find a way that successfully reads through the array index and picks out each and every word and assigns it to another array. So far I have tried setting up a Scanner that takes splitLines[] as a parameter, but I am unsure whether fileScanner.next{Int,Line,Double, etc.}() is capable of reading into the array index at all. I am unsure how to proceed from here. Here is the block that I have so far
import java.io.File;
import java.io.FileNotFoundException;
import java.lang.Math;
public class DrewCarey {
public static void main(String[] args) throws FileNotFoundException {
{
int min = 0;
int max = 52;
int randomIndex = (int)Math.floor(Math.random()*(max-min+1)+min);
String[] aPrize = new String[53];
int[] aPrice = new int[53];
final String DELIM = "\t";
Scanner fileScanner = new Scanner(new File("PrizeFile.txt"));
String fileLine = fileScanner.nextLine();
String[] splitLines = fileLine.split(DELIM);
String temp = "drew";
while(fileScanner.hasNextLine())
{
for(int i=0;i<aPrize.length;i++)
{
fileLine = fileScanner.nextLine();
splitLines = fileLine.split(DELIM);
if(fileLine.split(DELIM) != splitLines)
{
// String name = splitLines[0];
// int price = Integer.parseInt(splitLines[1]);
//splitLines[0] = aPrize[i];
// price = aPrice[i];
System.out.println(splitLines[0]);
// splitLines[0] = temp;
// splitLines[1] = temp;
}
}
}
fileScanner.close();
} ```

Your file/data is formatted in a very strange way which will cause all manner of issues, also are you splitting with "\n" or "/n" it is conflicting in your question. You should NOT use "\n" for the split because it is confused with an actual JAVA newline chracter. So assuming the file data is a single line that looks like this with "/n" and "/t":
<<Prize’s Name 0>>/t<<Prize’s Price 0>>/n <<Prize’s Name 1>>/t<<Prize’s Price 1>>/n <<Prize’s Name 2>>/t<<Prize’s Price 2>>/n <<Prize’s Name 3>>/t<<Prize’s Price 3>>/n <<Prize’s Name 4>>/t<<Prize’s Price 4>>
Then you can correctly split the first line of the file as shown below. The biggest problem in your code is that you only split with the "t" DELIM, never with the "n" delim. The below code solves this problem by splitting with "/n" first, then we split the resulting line with the "/t" and simply assign each part of the split to the aPrize and aPrice array.
//Add "\n" delim
final String DELIM_N = "/n ";
final String DELIM_T = "/t";
//We will use two string arrays in this demo for simplicity
String[] aPrize = new String[53];
String[] aPrice = new String[53];
Scanner fileScanner = new Scanner(new File("PrizeFile.txt"));
//Get first line
String fileLine = fileScanner.nextLine();
//Split line with "/n"
String[] splitLines = fileLine.split(DELIM_N);
//loop through array of split lines and save them in the Prize and Price array
for (int i = 0; i < splitLines.length; i++)
{
//Split each itom with "/t"
String[] splitItems = splitLines[i].split(DELIM_T);
//Check that each line does not have unexpected items
if (splitItems.length > 2)
{
System.out.println("Unexpected items found");
}
else
{
//Insert your code here to clean the input and remove the << and >> around items and parse them as an int etc.
//Assign the items to the array
//index 0 is prize
aPrize[i] = splitItems[0];
//and index 1 is price
aPrice[i] = splitItems[1];
}
}
//Complete. Print out the result with a loop
System.out.println("File read complete, Data split into two arrays:");
for (int i = 0; i < 10; i++)
{
System.out.println("Prize at index "+ i +" is: " + aPrize[i]);
System.out.println("Price at index "+ i +" is: " + aPrice[i]);
}
The output is as follows:
File read complete, Data split into two arrays:
Prize at index 0 is: <<Prize’s Name 0>>
Price at index 0 is: <<Prize’s Price 0>>
Prize at index 1 is: <<Prize’s Name 1>>
Price at index 1 is: <<Prize’s Price 1>>
...

I didn't understand your concern completely.
Try using ArrayList implementation of List instead of array.
Example:
List<String> aPrice = new ArrayList<>();
aPrice.add("some string");
You cant add more elements to array. ArrayList internally uses array,
but has methods to extend the number of elements stored.
You can retrieve elements by index as well.
You can use Arrays.asList() method to convert array to list if required.
You can check out the docs for more : ArrayList Documentation

Related

Java Scanner Split ArrayOutOfBounds

I am trying to make program that have a different behavior when the user inputs certain arguments to a String that is received by the program through a Scanner. My problem is the fact that i want to make it as if the user doesn't write the 2nd argument for example, the program should still work.
static String ReadString() {
Scanner scan = new Scanner(System.in);
return scan.nextLine();
}
String command = ReadString();
String words[]=new String[4];
words[0]="empty";
words[1]="empty";
words[2]="empty";
words[3]="empty";
words = command.split(" ");
The problem is that if I am calling for example words[1] after the user has written only one argument to that string, I still get the error ArrayOutOfBounds, although there should be an string with the value "empty".
Example:
User writes : ababbbbb command1 >>> when I call words[1] it should give me command1
User writes : ababbbbb >>> when I call words[1] it should give me empty
Because, when you wrote below code that means words which is Array of String type is pointing to reference, which is allocated memory to hold 4 string.
String words[]=new String[4];
Now, below line of code where you are creating Array by spliting them by " " has only size 1. Now, words variable reference has changed and it can only hold 1 String.
words = command.split(" ");
You need to make following correction :
String command = ReadString();
String words[]=new String[4];
String[] n = command.split(" ");
for(int i=0; i< 4; i++)
{
if((n.length-1)==i)
{
words[i]=n[i];
}
else
{
words[i]="empty";
}
}
>>>Demo<<<

Reading in from a file and adding to 2D array

I have two different programs, one which contains a method "addGrade" designed to add a new grade to a 2D array (gradeTable). One array of the 2D array is the category each grade should be in, and the second element is the grades for each category. Here is that program:
public class GradeBook {
private String name;
private char[] categoryCodes;
private String[] categories;
private double[] categoryWeights;
private double[][] gradeTable;
public GradeBook(String nameIn, char[] categoryCodesIn,
String[] categoriesIn, double[] categoryWeightsIn) {
name = nameIn;
categoryCodes = categoryCodesIn;
categories = categoriesIn;
categoryWeights = categoryWeightsIn;
gradeTable = new double[5][0];
}
public boolean addGrade(String newGradeIn) {
char row = newGradeIn.charAt(0);
int grade = Integer.parseInt(newGradeIn.substring(1));
double[] oldArr = gradeTable[row];
double[] newArr = Arrays.copyOf(oldArr, oldArr.length + 1);
newArr[newArr.length - 1] = grade;
gradeTable[row] = newArr;
return row != 0;
}
The second program reads in a file as a command argument. The bolded text represents the grades being read in. The letter stands for that category each grade should be in, and the number is the actual grade. The file is
Student1
5
a Activities 0.05
q Quizzes 0.10
p Projects 0.25
e Exams 0.30
f Final 0.30
**a100 a95 a100 a100 a100
q90 q80 q100 q80 q80 r90
p100 p95 p100 p85 p100
e77.5 e88
f92**
In the second program, I'm trying to loop through each grade in the file and call the addGrade method on it so it will be added to the 2D array. I'm unsure of how to call the method for each individual grade. Also, I'm pretty sure my addGrade method isn't right. Any help would be appreciated. This is the second program:
public class GradeBookApp {
String fileName = "";
String name = "";
char[] categoryCodes = new char[5];
String[] categories = new String[5];
double[] categoryWeights = new double[5];
double[][] gradeTable;
if (args.length > 0) {
for (int i = 0; i < args.length; i++) {
System.out.println("Reading file \"" + args[i] + "\"."
+ "\n\tCreating GradeBook object."
+ "\n\tAdding grades to GradeBook object."
+ "\nProcessing of file complete.");
fileName = args[i];
Scanner scanFile = new Scanner(new File(fileName));
name = scanFile.nextLine();
int catCodes = Integer.parseInt(scanFile.nextLine());
for (i = 0; i < catCodes; i++) {
String[] all = scanFile.nextLine().split(" ");
if(all.length == 3 && all[0].length() == 1 && all[2].matches("(\\d+\\.\\d+)")){
categoryCodes[i] = all[0].charAt(0);
categories[i] = all[1];
categoryWeights[i] = Double.parseDouble(all[2]);
}
}
GradeBook myGB = new GradeBook (name, categoryCodes,
categories, categoryWeights);
You'd be better off with having each list of grades as an ArrayList<Double> rather than a double[]. It's very hard work on the JVM (and on the programmer!) having to copy the whole array each time so that you can increase its length and add a new one. If you use an ArrayList<Double> gradeList, then you can just
gradeList.add(grade);
without needing to do all the copying.
I would also consider having the larger structure as a Map rather than an array. So rather than having a two-dimensional array, you could have a HashMap<Character,List<Double>> that maps the row onto the list of grades for that row. That avoids having to convert between characters and doubles, which you're currently (implicitly) doing.
Finally, the addGrade() method ought to take a char and a double (a row and a new grade), rather than a String: you're making a lot of work for yourself with having to process inappropriate data structures.
Once you've done this, calling addGrade for each item should be fairly easy. Once you've extracted a String representing a particular grade (say, String gr = "e77.5") then you can add to the list inside your HashMap gradeMap like this:
char row = gr.charAt(0);
double grade = Double.parseDouble(gr.substring(1));
gradeMap.get(row).add(grade);
I think you'll need to supply more info if you need more help than that.
You stated that you need to read from a file, but none of your code is actually reading from a file. This should be your first step. Try looking at BufferedReader documentation as well as numerous posts on this site regarding proper methods to perform file IO operations.
I'm assuming your storing your grades in the 2D gradeTable array like: {Category, grade}. You will need to read each row in your file(BufferedReader has methods for this), parse the string (Look at the String documentation, specifically split or substring/indexOf methods) into category and grade, and then populate your array.
Look into using more dynamic data structures, such as ArrayList. This will allow you to expand the size as you add more grades, as well as not having to copy your array into a new array every time the size expands.

Java - Importing text file into array when lines are not consistent

I have an assignment that pretty much has me stumped early on, the remainder of which is fairly easy (sorting the data once its imported and then saving it again under a different name).
We need to import data from a .txt file into 3 separate Arrays ( name, mascot, alias ) however the lines are not consistent. By consistent I mean one line may have:
Glebe,G Shield,Glebe District
While another line may have:
St George,Knight & Dragon,Saints,Dragons,St George Illawarra
Everything before the first , belongs to the name array.
Everything after the first , but before the second , belongs to the mascot array.
Everything after the second , till the end of the line belongs to the alias array.
I've been able to work out how to import the .txt file where it contains the entire line, which I was then able to convert into importing everything before a "," and new line (using Delimiters). However the lines that contain more then 3 sets of data ruin the import as the alias array only ends up holding 1 not everything else.
Thus does anyone know of and can show me a code that pretty much does:
name = Everything before the first ,
Mascot = Everything after the first , but before the second ,
Alias = Everything after the second , till the end of the line
That I could use as a base to work into mine?
After a day of research I've constantly come up with dead ends. They all generally involve splitting up at each comma but that breaks the import (lines with more then 1 alias, the second alias is put into the name array, ect)
This is the code I came up with that imports the entire line into an array:
public static void LoadData() throws IOException
{
String clubtxt = ("NRLclubs.txt");
String datatxt = ("NRLdata.txt");
int i, count;
File clubfile = new File(clubtxt);
File datafile = new File(datatxt);
if (clubfile.exists())
{
count = 0;
Scanner inputFile = new Scanner(clubfile);
i = 0;
while(inputFile.hasNextLine())
{
count++;
inputFile.nextLine();
}
String [] teamclub = new String[count];
inputFile.close();
inputFile = new Scanner(clubfile);
while(inputFile.hasNext())
{
teamclub[i] = inputFile.nextLine();
System.out.println(teamclub[i]);
i++;
}
inputFile.close();
}
else
{
System.out.println("\n" + "The file " + clubfile + " does not exist." + "\n");
}
if (datafile.exists())
{
count = 0;
Scanner inputFile = new Scanner(datafile);
i = 0;
while(inputFile.hasNextLine())
{
count++;
inputFile.nextLine();
}
String [] teamdata = new String[count];
inputFile.close();
inputFile = new Scanner(datafile);
while(inputFile.hasNext())
{
teamdata[i] = inputFile.nextLine();
System.out.println(teamdata[i]);
i++;
}
inputFile.close();
}
else
{
System.out.println("\n" + "The file " + datafile + " does not exist." + "\n");
}
}
Look at String.split method with the parameter limit.
When you have your input line in a variable called line, you can can call
String[] tokens = line.split(',', 3);
This will split the line on the commas, while making sure that it will not return more than 3 tokens. It returns an array of String in which the first element will be what is before the first comma, the second will be what is between the first and second commas, and the third element will be what is after the second comma.
Since you only want to parse on the first 2 commas, you can use String split with a limit.
If you prefer, you can use the String indexOf method to find the first 2 commas, then use the String substring method to get the characters between the commas.
You want to be able to handle a line with one comma, or no commas at all.
Here's one way to parse the String line
public List<String> splitLine(String line) {
List<String> list = new ArrayList<String>();
int firstPos = line.indexOf(",");
int secondPos = line.indexOf(",", firstPos + 1);
if (firstPos >= 0) {
if (secondPos >= 0) {
list.add(line.substring(0, firstPos));
list.add(line.substring(firstPos + 1, secondPos));
list.add(line.substring(secondPos + 1));
} else {
list.add(line.substring(0, firstPos));
list.add(line.substring(firstPos + 1));
list.add("");
}
} else {
list.add(line);
list.add("");
list.add("");
}
return list;
}
You can use the String.split method.
String line = // the line you read here
// Split on commas but only make three elements
String[] elements = line.split(',', 3);
// The first belongs to names
names[linecount] = elements[0];
// The second belongs to mascot
mascot[linecount] = elements[1];
// And the last belongs to aliases
aliases[linecount] = elements[2];
Try looking into the Pattern/Matcher stuff -- you need to come up with an appropriate regex.
http://docs.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html
Something like this might do it:
static final Pattern pattern = Pattern.compile("([^,]*),([^,]*),(*$)");
MatchResult result = pattern.matcher(line).toMatchResult();
if (result.groupCount() == 3) {
// Found the groups
name = result.group(0);
// etc..
} else {
// failed to match line
}
Basically what you want to do is split each line into an array as you read it in, and then parse the data line by line. Something like this (pseudocode):
Scanner inputFile = new Scanner(datafile);
while(inputFile.hasNextLine()) {
String line = inputFile.nextLine();
String[] lineSplit = line.split(",");
//TODO: make sure lineSplit is at least 3 long.
String name = lineSplit[0];
String mascot = lineSplit[1];
//EDIT: Don't just get the last element, get everything after the first two.
// You can do this buy just getting the substring of the length of those two strings
// + 2 to account for commas.
//String alias = lineSplit[lineSplit.length() - 1];
String alias = line.substring(name.length() + mascot.length() + 2);
//If you need to do trimming on the strings to remove extra whitespace, do that here:
name = name.trim();
mascot = mascot.trim();
alias = alias.trim();
//TODO: add these into the arrays you need.
}
Hope this helps.

Getting words from a file Inputs

I am trying to take in words from a file input that only contains strings and store each word separately into a single array (ArrayList is not allowed).
My code below takes in the file input, but takes it in as one chunk. For example, if the file input was "ONE TWO THREE" I want each word to have its own index in the array (array[0] = "ONE", array[1]="TWO" and array[2]="THREE") but my code below just takes the sentence and puts it all in array[0] = "ONE TWO THREE". How can I fix this?
int i = 0;
String wd = "";
while (in.hasNextLine() ) {
wd = in.nextLine() ;
array[i] = wd;
i++;
System.out.println("wd");
}
Thats happens because you a reading LINES from the file. You can do something like this:
String array[]=in.nextLine().split(" ");
f the file input was " ONE TWO THREE" i want each word to have its own
space in the array so array[0] = ONE, array1=TWO and array[2]=THREE
Use String#split(delim) with white space as delimiter.
String fileInput = "ONE TWO THREE";
String[] array = filrInput.split("\\s");
Instead of the line
array[i] = wd; // since wd is the whole line, this puts lines in the array
you want to split the line you read in and put the split items in your array.
String[] items = wd.split("\\s+"); // splits on any whitespace
for (String item : items) { // iterate through the items and shove them in the array
array[i] = item;
i++;
}
I would set the delimiter to space " " then use .next().
in.useDelimiter(" ");
while(in.hasNext()){
wd = in.next();
//wd will be one word
}

java store a string in a char array

In Java, How can I store a string in an array? For example:
//pseudocode:
name = ayo
string index [1] = a
string index [2] = y
string index [3] = o
Then how can I get the length of the string?
// this code doesn't work
String[] timestamp = new String[40]; String name;
System.out.println("Pls enter a name and surname");
Scanner sc = new Scanner(System.in);
name = sc.nextLine();
name=timestamp.substring(0, 20);
If you want a char array to hold each character of the string at every (or almost every index), then you could do this:
char[] tmp = new char[length];
for (int i = 0; i < length; i++) {
tmp[i] = name.charAt(i);
}
Where length is from 0 to name.length.
This code doesn't compile because the substring method can only be called on a String, not a String array if I'm not mistaken. In the code above, timestamp is declared as a String array with 40 indexes.
Also in this code, you're asking for input from a user and assigning it to name in this line:
name = sc.nextLine();
and then you are trying to replace what the user just typed with what is stored in timestamp on the next line which is nothing, and would erase whatever was stored in name:
name = timestamp.substring(0,20);
And again that wouldn't work anyway because timestamp is an array of 40 strings instead of one specific string. In order to call substring it has to be just one specific string.
I know that probably doesn't help much with what you're trying to do, but hopefully it helps you understand why this isn't working.
If you can reply with what you're trying to do with a specific example I can help direct you further. For example, let's say you wanted a user to type their name, "John Smith" and then you wanted to seperate that into a first and last name in two different String variables or a String array. The more specific you can be with what you want to do the better. Good luck :)
BEGIN EDIT
Ok here are a few things you might want to try if I understand what you're doing correctly.
//Since each index will only be holding one character,
//it makes sense to use char array instead of a string array.
//This next line creates a char array with 40 empty indexes.
char[] timestamp = new char[40];
//The variable name to store user input as a string.
String name;
//message to user to input name
System.out.println("Pls enter a name and surname");
//Create a scanner to get input from keyboard, and store user input in the name variable
Scanner sc = new Scanner(System.in);
name = sc.nextLine();
//if you wanted the length of the char array to be the same
//as the characters in name, it would make more sense to declare it here like this
//instead of declaring it above.
char[] timestamp = new char[name.length()];
//For loop, loops through each character in the string and stores in
//indexes of timestamp char array.
for(int i=0; i<name.length;i++)
{
timestamp[i] = name.charAt(i);
}
The other thing you could do if you wanted to just seperate the first and last name would be to split it like this.
String[] seperateName = name.split(" ");
That line will split the string when it finds a space and put it in the index in the seperateName array. So if name was "John Smith", sperateName[0] = John and seperateName[1] = Smith.
Are you looking for a char[]? You can convert a character array to a String using String.copyValueOf(char[]).
Java, substring an array:
Use Arrays.copyOfRange:
public static <T> T[] copyOfRange(T[] original,
int from,
int to)
For example:
import java.util.*;
public class Main{
public static void main(String args[]){
String[] words = new String[3];
words[0] = "rico";
words[1] = "skipper";
words[2] = "kowalski";
for(String word : words){
System.out.println(word);
}
System.out.println("---");
words = Arrays.copyOfRange(words, 1, words.length);
for(String word : words){
System.out.println(word);
}
}
}
Prints:
rico
skipper
kowalski
---
skipper
kowalski
Another stackoverflow post going into more details:
https://stackoverflow.com/a/6597591/445131

Categories