Java loop through each unique value - java

I have a csv file like this:
"user1","track1","player1"
-------------------------
"user1","track2","player2"
-------------------------
"user1","track3","player3"
-------------------------
"user1","track4","player4"
-------------------------
"user2","track2","player3"
-------------------------
.
.
"userN","trackM","playerX"
What I need to do is to divid tracks and players related to each user into a half and put them in separate files.
For example, for user1, if it has 4 lines, I need to divid it into two parts (the first two lines in file A, and the rest in file B), and repeating the same action for all users.
This is what I wrote so far:
public static void main(String[] args) throws java.lang.Exception {
BufferedReader userlines = new BufferedReader(new FileReader("/Users/mona/Documents/Bolzano/Datasets/Lastfm_Matthias/lastfm_usertrackplayer.csv"));
String uLine = null;
while ((uLine = userlines.readLine()) != null) {
String[] userId = uLine.split(",");
ArrayList<String> list = new ArrayList<String>();
list.add(uLine);
for(int i=0; i<=list.size();i++){
// --> THIS FOR CONDITION IS MY PROBLEM,I need s.th like for(i=0; i<=(last unique userId (i.e., length of userId[i]) until it reaches the next unique userId)
//Divide the lines and put into two separate files
}
}
userlines.close();
}
Sorry I know it should be something simple, but I really could not find any related/similar question by googling my problem :(
Could someone help me please?
Thanks

You cannot know "a priori" the number of lines for each user.
So you must memorize (in a List for example) all lines for the current user until you read the next user. Then save, in both files, the content of the list.
Clean the list, do the same thing for the next user.
EDIT
public static void main(String[] args) throws java.lang.Exception {
try(BufferedReader userlines = new BufferedReader(new FileReader("/Users/mona/Documents/Bolzano/Datasets/Lastfm_Matthias/lastfm_usertrackplayer.csv"));) {
String uLine = null;
ArrayList<String> list = new ArrayList<String>();
String currentUserId = null;
while ((uLine = userlines.readLine()) != null) {
String[] userData = uLine.split(",");
String userId = userData[0]; // <-- get User ID here
if (userId.equals(currentUserId)) {
// Do what ever you need while buffering same userId
} else {
// Save currentUserId in file
yourSaveMethod(list);
currentUserId = userId;
list.clear();
}
list.add(uLine);
}
}
}

You can use StringTokenizer class for parsing data.
Example:
String str = "user1, track1, player1";
StringTokenizer st = new StringTokenizer(str);
System.out.println("---- Split by space ------");
while (st.hasMoreElements()) {
System.out.println(st.nextElement());
}
System.out.println("---- Split by comma ',' ------");
StringTokenizer st2 = new StringTokenizer(str, ",");
while (st2.hasMoreElements()) {
System.out.println(st2.nextElement());
}

Related

Read File into ArrayList from .txt file on begging of program

So i got a Java Class of Konto, which got:
private String navn;
private int medlemdsnummer;
private String årstal;
private String måned;
private String dag;
LocalDate localDate;
They are used like this:
ArrayList<Konto> kontoArrayList = new ArrayList<>();
And I save my ArrayList to a .txt document before the program shutdowns:
private static void saveToFile(ArrayList<Konto> kontoArrayList) throws IOException {
String content = new String(Files.readAllBytes(Paths.get("medlemmer.txt")));
PrintStream printStream = new PrintStream("medlemmer.txt");
for (int i = 0; i < kontoArrayList.size(); i++) {
printStream.println(content + kontoArrayList.get(i).getMedlemdsnummer() + ": " + kontoArrayList.get(i).getNavn() + " " +
kontoArrayList.get(i).getLocalDate());
}
}
They end up looking like this in the .txt file:
1: Kasper 1996-11-20
2: Jonas 1996-04-27
3: Jesper 1996-05-14
Okay, so far so good. Now for the question: When the program is turned on, I want to make it able to load the .txt file from the beginning and "transfer" it to an ArrayList of Konto. So that i later can use my method (addNewMember). I saw a lot of example on the internet, but they all use:
ArrayList<String> somename = new ArrayList<String>();
I want to use:
ArrayList<Konto> konto = new ArrayList<Konto>();
Is this possible, if so how do to?
If not what could i do instead?
Thanks in advance, Victor.
You can read all lines from the file as string and split this strings by spaces.
And then create new objects with parsing of options.
Something like this:
List<String> strings = Files.readAllLines(Paths.get("test.txt"));
List<Konto> kontos = new ArrayList<>();
for (String string : strings) {
String[] data = string.split(" ");
kontos.add(new Konto(data[1], new Date(data[2])));
}
Or using Streams:
List<Konto> kontos = Files.lines(Paths.get("test.txt")) // String
.map(line -> line.split(" ")) // String[]
.map(data -> new Konto(data[1], new Date(data[2])) // Konto
.collect(Collectors.toList());
Something like the following, you've got to check it
class TestParse {
public TestParse(String line) {
StringTokenizer tokenizer = new StringTokenizer(line, ",");
if(tokenizer.countTokens() != 3) {
throw new RuntimeException("error");
}
s1 = tokenizer.nextToken();
s2 = tokenizer.nextToken();
s3 = tokenizer.nextToken();
}
private String s1;
private String s2;
private String s3;
}
public class TestRead {
public static void main(String[] args) throws Exception {
List<TestParse> testParses = new ArrayList<TestParse>();
BufferedReader in = new BufferedReader(new FileReader("file.txt"));
String line;
while((line = in.readLine()) != null) {
testParses.add(new TestParse(line));
}
in.close();
}
}
I think one way you can try is read line by line, and define a Konto constructor that accept a string.
Edit: You can follow the below answer from Lucem. But I think I will do it a little different
List<String> strings = Files.readAllLines(Paths.get("fileName.txt"));
List<Konto> kontos = new ArrayList<>();
for (String s: strings) {
kontos.add (new Konto(s))
}
or using Streams:
List<Konto> kontos = Files.lines(Paths.get("fileName.txt"))
.map(line -> new Konto(line));
.collect(Collectors.toList());
And then in Konto class add a constructor that accept a string and manipulate it. Because you didn't add the class Konto here, I didn't know the exact name of your properties, so I let it be "yourPropertyNumber", "yourPropertyString" and "yourPropertyDate"
class Konto {
public Konto (String input) {
// Split based on white space
String[] dataParts = input.split(" ");
// Get rid of the semicolon
String number = dataParts[0].substring(0, dataParts[0].length - 1);
yourPropertyNumber = parseInt(number);
yourPropertyString = dataParts[1];
yourPropertyDate = new Date(dataParts[2]);
}
// Your other code here
}
The reason I want to pass a String to a constructor rather than parse the string where I read the file is that I think it is easier to debug or make change in the way it reads the string.
Hope this help.

Reading a text file into multiple arrays in Java

I'm currently working on a program that reads in a preset text file and then manipulates the data in various ways. I've got the data manipulation to work with some dummy data but I still need to get the text file read in correctly.
The test file looks like this for 120 lines:
Aberdeen,Scotland,57,9,N,2,9,W,5:00,p.m. Adelaide,Australia,34,55,S,138,36,E,2:30,a.m. Algiers,Algeria,36,50,N,3,0,E,6:00,p.m.(etc etc)
So each of these needs to be read into its own array, in order String[] CityName,String[] Country,int[] LatDeg,int[] LatMin,String[] NorthSouth,int[] LongDeg,int LongMin,String[] EastWest,int[] Time.String[] AMPM
So the problem is that while I'm reasonably comfortable with buffered readers, designing this particular function has proven difficult. In fact, I've been drawing a blank for the past few hours. It seems like it would need multiple loops and counters but I can't figure out the precisely how.
I am assuming that you have one city per line type of file structure. If it is not, it will require a bit of tweaking in the following solution:
I will do the following way if I am more comfortable with BufferReader as you say:
List<List<String>> addresses = new ArrayList<List<String>>();
try(BufferedReader br = new BufferedReader(new FileReader(file))) {
for(String line; (line = br.readLine()) != null; ) {
addresses.add(line.split(","));
}
}
Later, let's say you want to retrieve the country information of say 'Adelaid', you can try the following:
for (List<String> cityInfo : addresses) {
if("Adelaid".equals(cityInfo.get(0)) {
country = cityInfo.get(1);
}
}
Instead of creating different arrays (like String[] CityName,String[] Country, etc.,), try using a Domain Object.
Here, you can have a Domain object or Custom class Location with attributes
public class Location
{
private String cityName;
private String country;
private String latDeg;
etc
getters();
setters();
}`
Then you can write a file reader, each line item in the file will be a Location. So result will have
Location[] locations;
or
List locations;`
To carry out this task I should think the first thing you want to do is establish how many lines of data actually exist within the data file. You say it is 120 lines but what if it happens that it will be more or less? We would want to know exactly what it is so as to properly initialize all our different Arrays. We can use a simple method to accomplish this, let's call it the getFileLinesCount() method which will ulitmately return a Integer value that would be the number of text lines the data file holds:
private int getFileLinesCount(final String filePath) {
int lines = 0;
try{
File file =new File(filePath);
if(file.exists()){
FileReader fr = new FileReader(file);
try (LineNumberReader lnr = new LineNumberReader(fr)) {
while (lnr.readLine() != null){ lines++; }
}
}
else {
throw new IllegalArgumentException("GetFileLinesCount() Method Error!\n"
+ "The supplied file path does not exist!\n(" + filePath + ")");
}
}
catch(IOException e){ e.printStackTrace(); }
return lines;
}
Place this method somewhere within your main class. Now you need to Declare and initialize all your Arrays:
String filePath = "C:\\My Files\\MyDataFile.txt";
int lines = getFileLinesCount(filePath);
String[] CityName = new String[lines];
String[] Country = new String[lines];
int[] LatDeg = new int[lines];
int[] LatMin = new int[lines];
String[] NorthSouth = new String[lines];
int[] LongDeg = new int[lines];
int[] LongMin = new int[lines];
String[] EastWest = new String[lines];
int[] Time = new int[lines];
String[] AMPM = new String[lines];
Now to fill up all those Arrays:
public static void main(String args[]) {
loadUpArrays();
// Do whatever you want to do
// with all those Arrays.....
}
private void loadUpArrays() {
// Read in the data file.
try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
String sCurrentLine;
int x = 0;
// Read in one line at a time and Fill the Arrays...
while ((sCurrentLine = br.readLine()) != null) {
// Split each line read into an array upon itself.
String[] fileLine = sCurrentLine.split(",");
// Fill our required Arrays...
CityName[x] = fileLine[0];
Country[x] = fileLine[1];
LatDeg[x] = Integer.parseInt(fileLine[2]);
LatMin[x] = Integer.parseInt(fileLine[3]);
NorthSouth[x] = fileLine[4];
LongDeg[x] = Integer.parseInt(fileLine[5]);
LongMin[x] = Integer.parseInt(fileLine[6]);
EastWest[x] = fileLine[7];
Time[x] = Integer.parseInt(fileLine[8]);
AMPM[x] = fileLine[9];
x++;
}
br.close();
}
catch (IOException ex) { ex.printStackTrace(); }
}
Now, I haven't tested this, I just quickly punched it out but I think you can get the jest of it.
EDIT:
As #Mad Physicist has so graciously pointed out within his comment below, a List can be used to eliminate the need to count file lines therefore eliminating the need to read the data file twice. All the file lines can be placed into the List and the number of valid file lines can be determined by the size of the List. Filling of your desired arrays can now also be achieved by iterating through the List elements and processing the data accordingly. Everything can be achieved with a single method we'll call fillArrays(). Your Arrays declaration will be a little different however:
String[] CityName;
String[] Country;
int[] LatDeg;
int[] LatMin;
String[] NorthSouth;
int[] LongDeg;
int[] LongMin;
String[] EastWest;
String[] Time;
String[] AMPM;
public static void main(String args[]) {
fillArrays("C:\\My Files\\MyDataFile.txt");
// Whatever you want to do with all
// those Arrays...
}
private void fillArrays(final String filePath) {
List<String> fileLinesList = new ArrayList<>();
try{
File file = new File(filePath);
if(file.exists()){
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
String strg;
while((strg = br.readLine()) != null){
// Make sure there is no blank line. If not
// then add line to List.
if (!strg.equals("")) { fileLinesList.add(strg); }
}
br.close();
}
}
else {
throw new IllegalArgumentException("GetFileLinesCount() Method Error!\n"
+ "The supplied file path does not exist!\n(" + filePath + ")");
}
// Initialize all the Arrays...
int lines = fileLinesList.size();
CityName = new String[lines];
Country = new String[lines];
LatDeg = new int[lines];
LatMin = new int[lines];
NorthSouth = new String[lines];
LongDeg = new int[lines];
LongMin = new int[lines];
EastWest = new String[lines];
Time = new String[lines];
AMPM = new String[lines];
// Fill all the Arrays...
for (int i = 0; i < fileLinesList.size(); i++) {
String[] lineArray = fileLinesList.get(i).split(",");
CityName[i] = lineArray[0];
Country[i] = lineArray[1];
LatDeg[i] = Integer.parseInt(lineArray[2]);
LatMin[i] = Integer.parseInt(lineArray[3]);
NorthSouth[i] = lineArray[4];
LongDeg[i] = Integer.parseInt(lineArray[5]);
LongMin[i] = Integer.parseInt(lineArray[6]);
EastWest[i] = lineArray[7];
Time[i] = lineArray[8];
AMPM[i] = lineArray[9];
}
}
catch(IOException e){ e.printStackTrace(); }
}
On another note...your Time Array can not be Integer since in data, what is considered the time contains a colon (:) which is a alpha character therefore (in case you haven't noticed) I have changed its declaration to String[]

need to find remove duplicates from a text file comparing 1st and 5th string from every line

As part of a project I'm working on, I'd like to clean up a file I generate of duplicate line entries. These duplicates often won't occur near each other, however. I came up with a method of doing so in Java (which basically find a duplicates in the file, I stored two strings in two arrayLists and iterating but it was not working because of nested for loops i am getting into the condition manyways.
I need an integrated solution for this, however. Preferably in Java. Any ideas?
List item
public class duplicates {
static BufferedReader reader = null;
static BufferedWriter writer = null;
static String currentLine;
public static void main(String[] args) throws IOException {
int count=0,linecount=0;;
String fe = null,fie = null,pe=null;
File file = new File("E:\\Book.txt");
ArrayList<String> list1=new ArrayList<String>();
ArrayList<String> list2=new ArrayList<String>();
reader = new BufferedReader(new FileReader(file));
while((currentLine = reader.readLine()) != null)
{
StringTokenizer st = new StringTokenizer(currentLine,"/"); //splits data into strings
while (st.hasMoreElements()) {
count++;
fe=(String) st.nextElement();
//System.out.print(fe+"/// ");
//System.out.println("count="+count);
if(count==1){ //stores 1st string
pe=fe;
// System.out.println("first element "+fe);
}
else if(count==5){
fie=fe; //stores 5th string
// System.out.println("fifth element "+fie);
}
}
count=0;
if(linecount>0){
for(String s1:list1)
{
for(String s2:list2){
if(pe.equals(s1)&&fie.equals(s2)){ //checking condition
System.out.println("duplicate found");
//System.out.println(s1+ " "+s2);
}
}
}
}
list1.add(pe);
list2.add(fie);
linecount++;
}
}
}
i/p:
/book1/_cwc/B737/customer/Special_Reports/
/Airbook/_cwc/A330-200/customer/02_Watchlists/
/book1/_cwc/B737/customer/Special_Reports/
/jangeer/_cwc/Crj_200/customer/plots/
/Airbook/_cwc/A330-200/customer/02_Watchlists/
/jangeer/_cwc/Crj_200/customer/06_Performance_Summaries/
/jangeer/_cwc/Crj_200/customer/02_Watchlists/
/jangeer/_cwc/Crj_200/customer/01_Highlights/
/jangeer/_cwc/ERJ170/customer/01_Highlights/
o/p:
/book1/_cwc/B737/customer/Special_Reports/
/Airbook/_cwc/A330-200/customer/02_Watchlists/
/jangeer/_cwc/Crj_200/customer/plots/
/jangeer/_cwc/Crj_200/customer/06_Performance_Summaries/
/jangeer/_cwc/Crj_200/customer/02_Watchlists/
/jangeer/_cwc/Crj_200/customer/01_Highlights/
Use a Set<String> instead of Arraylist<String>.
Duplicates aren't allowed in a Set, so if you just add everyline to it, then get them back out, you'll have all distinct strings.
Performance-wise it's also quicker than your nested for-loop.
public static void removeDups() {
String[] input = new String[] { //Lets say you read whole file in this string array
"/book1/_cwc/B737/customer/Special_Reports/",
"/Airbook/_cwc/A330-200/customer/02_Watchlists/",
"/book1/_cwc/B737/customer/Special_Reports/",
"/jangeer/_cwc/Crj_200/customer/plots/",
"/Airbook/_cwc/A330-200/customer/02_Watchlists/",
"/jangeer/_cwc/Crj_200/customer/06_Performance_Summaries/",
"/jangeer/_cwc/Crj_200/customer/02_Watchlists/",
"/jangeer/_cwc/Crj_200/customer/01_Highlights/",
"/jangeer/_cwc/ERJ170/customer/01_Highlights/"
};
ArrayList<String> outPut = new ArrayList<>(); //The array list for storing output i.e. distincts.
Arrays.stream(input).distinct().forEach(x -> outPut.add(x)); //using java 8 and stream you get distinct from input
outPut.forEach(System.out::println); //I will write back to the file, just for example I am printing out everything but you can write back the output to file using your own implementation.
}
The output when I ran this method was
/book1/_cwc/B737/customer/Special_Reports/
/Airbook/_cwc/A330-200/customer/02_Watchlists/
/jangeer/_cwc/Crj_200/customer/plots/
/jangeer/_cwc/Crj_200/customer/06_Performance_Summaries/
/jangeer/_cwc/Crj_200/customer/02_Watchlists/
/jangeer/_cwc/Crj_200/customer/01_Highlights/
/jangeer/_cwc/ERJ170/customer/01_Highlights/
EDIT
Non Java 8 answer
public static void removeDups() {
String[] input = new String[] {
"/book1/_cwc/B737/customer/Special_Reports/",
"/Airbook/_cwc/A330-200/customer/02_Watchlists/",
"/book1/_cwc/B737/customer/Special_Reports/",
"/jangeer/_cwc/Crj_200/customer/plots/",
"/Airbook/_cwc/A330-200/customer/02_Watchlists/",
"/jangeer/_cwc/Crj_200/customer/06_Performance_Summaries/",
"/jangeer/_cwc/Crj_200/customer/02_Watchlists/",
"/jangeer/_cwc/Crj_200/customer/01_Highlights/",
"/jangeer/_cwc/ERJ170/customer/01_Highlights/"
};
LinkedHashSet<String> output = new LinkedHashSet<String>(Arrays.asList(input)); //output is your set of unique strings in preserved order
}

String tokenizer and Scanner java

I have a large text file which I want to separate into different strings using the delimiter !- (Each string is multiple lines).
I then want to discard all the other strings that do not contain:
=========== ALL OBJECTS IN CLASS: FENESTRATIONSURFACE:DETAILED ===========
So far I've got this and its not outputting anything (it complies but no output to console).I'm new to programming and I'm not making much progress after researching this for sometime so any suggestions or pointers would be most appreciated thanks!
public class Main {
public static void main(String[] args) throws FileNotFoundException {
File file = new File("C:/Users/Anton/Pictures/1 x geotransform0.5m shading.txt");
Scanner scan = new Scanner(file);
while(scan.hasNextLine()){
StringTokenizer st = new StringTokenizer(scan.nextLine(),"!-");
if(st.equals(" =========== ALL OBJECTS IN CLASS: FENESTRATIONSURFACE:DETAILED ===========")) {
System.out.print(st);
}
}
scan.close();
}
}
You should consider reading the java doc page to StringTokenizer: http://docs.oracle.com/javase/7/docs/api/java/util/StringTokenizer.html
There two different problems in your code:
Because your desired strings are more than one line out of a file, you first have to add them up (into a String) and then work with it via StringTokenizer to separate again.
You have to compare the StringTokenizer.nextToken() to your check String not the whole StringTokenizer. StringTokenizer.nextToken() then gives you the next String separated through !-.
The following code should work:
public class Main {
public static void main(String[] args) throws FileNotFoundException {
File file = new File("C:/Users/Anton/Pictures/1 x geotransform0.5m shading.txt");
Scanner scan = new Scanner(file);
//Scanning
//first scan the whole file into a string (because a sting can have more than one line)
String temp = "";
while(scan.hasNextLine()){
temp = scan.nextLine();
}
//now add the string to tokeinzer
StringTokenizer st = new StringTokenizer(temp,"!-");
//now give output
while(st.hasMoreTokens()){
String temp2 = st.nextToken();
if(temp2.equals(" =========== ALL OBJECTS IN CLASS: FENESTRATIONSURFACE:DETAILED ===========")) {
System.out.print(temp2);
}
}
scan.close();
}
}
}
remove the if condition and add the below while condition
while (st.hasMoreElements()) {
System.out.println(st.nextElement());
}
because stringtokenizer splits the text based on token. so your if never becomes true.
try this...........
while(scan.hasNextLine()){
StringTokenizer st = new StringTokenizer(scan.nextLine(),"!-");
while(st.hasMoreTokens()){
String stt = st.nextElement().toString();
if(stt.equals("=========== ALL OBJECTS IN CLASS: FENESTRATIONSURFACE:DETAILED ===========")) {
System.out.print(stt);
}
}
}
you comparing string with stringtokenizer object not value....

How to find certain words in a text file, then find numbers in Java?

I have the following text file (answers.txt):
Problem A: 23|47|32|20
Problem B: 40|50|30|45
Problem C: 5|8|11|14
Problem D: 20|23|25|30
What I need is something that will read the problem that I tell it(Problem A, Problem B), then read the numbers after it, which are separated by the lines, and print it out like this:
Answers for Problem A: a.23 b.47 c.32 d.20
Does anyone know how this can be done? I've been stuck on it for a while.
Read the lines one by one, split the lines at " " first. The you will get an array with three parts "Problem", "A:" and "23|47|32|20". Then split the third part at "|" so you will get a second array with four parts "23,"47","32","20".
Combine all to get the output you want.
If you want info on how to read lines from a file, or spilt strings then there are billions of tutorials online on how to do that so I wont go into detail on how its done. IM sure you can find them.
Check out this code!
It assumes that you have such file format:
Problem A:
23|7|32|20
Problem B:
40|50|30|45
Problem C:
5|8|11|14
Problem D:
20|23|25|30
because you wrote "numbers after it, which are separated by the lines"
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
public class Demo {
public static void main(String[] args) throws FileNotFoundException {
Scanner sc = new Scanner(new File("answers.txt"));
List<String> dataList = new ArrayList<String>();
while(sc.hasNextLine()){
dataList.add(sc.nextLine());
}
System.out.println(dataList);
Map<String,String> map = new HashMap<String,String>();
for(int i=0;i<dataList.size();i=i+2){
map.put(dataList.get(i),dataList.get(i+1));
}
for(Entry<String,String> en:map.entrySet()){
System.out.println(en.getKey()+" : "+en.getValue());
}
String problemC = map.get("Problem C:");
String splitted[] = problemC.split("\\|");
System.out.println("Get me problem C: "+String.format("a:%s, b:%s, c:%s, d:%s",splitted[0],splitted[1],splitted[2],splitted[3]));
}
}
Hope this helps!
public static void main(String args[])
{
BufferedReader br = new BufferedReader(new FileReader(new File("answers.txt")));
String lineRead = null;
String problem = "Problem A";//Get this from user Input
List<String> numberData = new ArrayList<String>();
while((lineRead = br.readLine())!=null)
{
if(lineRead.contains(problem))
{
StringTokenizer st = new StringTokenizer(lineRead,":");
String problemPart = st.nextToken();
String numbersPart = st.nextToken();
st = new StringTokenizer(lineRead,"|");
while(st.hasMoreTokens())
{
String number = st.nextToken();
System.out.println("Number is: " + number);
numberData.add(number);
}
break;
}
}
System.out.println("Answers for " + problem + " : " + numberData );
}
Read the lines one by one, split the lines with :. The you will get an array with two parts "Problem A:" and "23|47|32|20". Then split the second part at "|" so you will get a second array with four parts "23,"47","32","20".
Combining all this you will get the output you want.
Cheers!
Use java.util.Scanner and you can filter the integers in the file.
Scanner s = new Scanner (new File ("answers.txt")).useDelimiter("\\s+");
while (s.hasNext()) {
if (s.hasNextInt()) { // check if next token is integer
System.out.print(s.nextInt());
} else {
s.next(); // else read the next token
}
}
Do you know how to read line by line ? If not , chect it How to read a large text file line by line in java?
To sub your string data there have many ways to do. You can sub as you wish. Here for my code..
String data = yourReader.readLine();
String problem = data.substring("Problem".length(), data.indexOf(":"));
System.err.println("Problem is " + problem);
data = data.substring(data.indexOf(":") + 2, data.length());
String[] temp = data.split("\\|");
for (String result : temp) {
System.out.println(result);
}
Assuming there are always four possible answers as in your Example:
// read complete file in fileAsString
String regex = "^(Problem \\w+): (\\d+)\\|(\\d+)\\|(\\d+)\\|(\\d+)$";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(fileAsString);
//and so on, read all the Problems using matcher.find() and matcher.group(int) to get the parts
// put in a Map maybe?
// output the one you want...
I might suggest creating a simple data type for the purpose of organization:
public class ProblemAnswer {
private final String problem;
private final String[] answers;
public ProblemAnswer(String problem, String[] answers) {
this.problem = problem;
this.answers = new String[answers.length];
for (int i = 0; i < answers.length; i++) {
this.answers[i] = answers[i];
}
}
public String getProblem() {
return this.problem;
}
public String[] getAnswers() {
return this.answers;
}
public String getA() {
return this.answers[0];
}
public String getB() {
return this.answers[1];
}
public String getC() {
return this.answers[2];
}
public String getD() {
return this.answers[3];
}
}
Then the reading from the text file would look something like this:
public void read() {
Scanner s = new Scanner("answers.txt");
ArrayList<String> lines = new ArrayList<String>();
while (s.hasNext()) {
lines.add(s.nextLine());//first separate by line
}
ProblemAnswer[] answerKey = new ProblemAnswer[lines.size()];
for (int i = 0; i < lines.size(); i++) {
String[] divide = lines.get(i).split(": "); //0 is the problem name, 1 is the list
//of answers
String[] answers = divide[1].split("|"); //an array of the answers to a given
//question
answerKey[i] = new ProblemAnswer(divide[0], answers); //add a new ProblemAnswer
//object to the key
}
}
Now that leaves you with an answer key with ProblemAnswer objects which is easily checked
with a simple .equals() comparison on the getProblem() method, and whatever index is matched, you have all the answers neatly arranged right within that same object.

Categories

Resources