I have the following code:
public class generator {
public static void main(String[] args) throws FileNotFoundException {
Scanner s = new Scanner(new File("results.txt"));// creates a scanner to
// scan from a file
String line;
String HomeTeam, AwayTeam;
while (s.hasNext()) {
line = s.nextLine(); // reads the next line from the file
line = line.trim(); // trims the line
String[] elements = line.split(":"); // splits the line
if (elements.length == 4) {
HomeTeam = elements[0].trim(); // trims home team
AwayTeam = elements[1].trim(); // trims away team
elements[2] = elements[2].trim();
elements[3] = elements[3].trim();
if (HomeTeam.length() != 0 && AwayTeam.length() != 0) { // check if position is present
try { // "try" is a special statement which allows us to deal with "exceptions"
int HomeScore = Integer.parseInt(elements[2]); // attempt to convert the String into an Integer type value
int AwayScore = Integer.parseInt(elements[3]);
System.out.println(HomeTeam + " ["+ HomeScore +"]" + " | " + AwayTeam + " ["+AwayScore+"]");
}
catch (NumberFormatException e) {
}
}
}
}
}
}
Now my question is: how do I count the valid and invalid lines as well as total number of score in entire file?
Sample input file is:
Leeds United : Liverpool : 1 : 2
Chelsea : Manchester City : 1 : 1
Aston Villa : Middlesbrough : 3 : 1
Tottenham Hotspur : Stoke City : 0 : 0
West Ham United : Wigan Athletic :2 : 1
Fulham : Liverpool : 1 : 2
Wigan Athletic : Leeds United : 2 : 2
Arsenal Liverpool :2:2
Hull City: Tottenham Hotspur : 3 : 5
Everton : Portsmouth:4 : 2
Stoke City : West Bromwich Albion : 5 : 4
Leeds United : Liverpool : 1: 10
Blackburn Rovers : Fulham : 1 : 1
West Ham United : Newcastle United : 0 : 0
Manchester United : Wigan Athletic : 1 : 2
Hull City : Sunderland : 2 : 3
Chelsea : Manchester City :1
Fulham : Leeds United : 1 : 2
Wigan Athletic : Tottenham Hotspur : 2 : 2
Hull City : Everton : 3 : 5
: :2:0
Sunderland : Blackburn Rovers : 4 : 2
Stoke City : West Bromwich Albion : 5 : 4
Hull : Liverpool : 5: x
Blackburn Rovers : Fulham : 1 : 1
Chelsea : Everton : a : 1
Sunderland : Newcastle United : 0 : 0
Hull : :2:3
Sunderland : Blackburn Rovers : 1 : 2
Hull City : Everton : 2 : 3
Leeds United : Chelsea : 1 : 2
Chelsea : Manchester City : 1 : 1
Aston Villa:Fulham:3:1
Manchester City : Stoke City : 0 : 0
West Ham United : Middlesbrough : 2 : 1
Actually You check validity so what's the problem with counting? Create two variables: ValidNumb and InvalidNumb. Increase ValidNumb after System.out.println(). Increase InvalidNumb if elements.length not equal 4, lenght of team names equal 0 or You catch exception during conversions scores to integers.
To count all scores: create one more variable allScores and add them to HomeScore and AwayScore in try block.
public static void main(String[] args) throws FileNotFoundException {
Scanner s = new Scanner(new File("results.txt"));// creates a scanner to
// scan from a file
String line;
String HomeTeam, AwayTeam;
Int ValidNumb = 0, InvalidNumb = 0; //counters of valid and invalid lines
Int AllScores = 0; //sum of all goals
while (s.hasNext()) {
line = s.nextLine(); // reads the next line from the file
line = line.trim(); // trims the line
String[] elements = line.split(":"); // splits the line
if (elements.length == 4) {
HomeTeam = elements[0].trim(); // trims home team
AwayTeam = elements[1].trim(); // trims away team
elements[2] = elements[2].trim();
elements[3] = elements[3].trim();
if (HomeTeam.length() != 0 && AwayTeam.length() != 0) { // check if position is present
try { // "try" is a special statement which allows us to deal with "exceptions"
int HomeScore = Integer.parseInt(elements[2]); // attempt to convert the String into an Integer type value
int AwayScore = Integer.parseInt(elements[3]);
AllScores = AllScores + HomeScore + AwayScore; //sum up scores
System.out.println(HomeTeam + " ["+ HomeScore +"]" + " | " + AwayTeam + " ["+AwayScore+"]");
ValidNumb++; //line is valid
}
catch (NumberFormatException e) {
InvalidNumb++; //scores are not integers
}
}
else {InvalidNumb++;} //HomeTeam or AwayTeam are empty
}
else {InvalidNumb++;} //not enough elements in line
}
}
So you would need counter variables for every metrics that you need.So before your while loop define them as:
int totalAwayScore = 0, totalHomeScore = 0, invalidLines = 0, totalLines = 0;
Within while loop, increment totalLines as
totalLines++;
which means you have next line to read. Your try catch is where you know how much is score so keep on adding to metrics that you defined above like:
try { // "try" is a special statement which allows us to deal with "exceptions"
int HomeScore = Integer.parseInt(elements[2]); // attempt to convert the String into an Integer type value
int AwayScore = Integer.parseInt(elements[3]);
totalAwayScore += AwayScore;
totalHomeScore += HomeScore;
System.out.println(HomeTeam + " ["+ HomeScore +"]" + " | " + AwayTeam + " ["+AwayScore+"]");
} catch (NumberFormatException e) {
invalidLines++;
}
Here if you get number format exception, you get to know that it's invalid line and hence increment the value of variable that holds invalid lines in a file.
At the end of the while loop you print the stats like:
System.out.println("Total home score is " + totalHomeScore + " totalAway score is " + totalAwayScore + " invalid lines were " + invalidLines + " of total " + totalLines);
I'm not sure I understood but:
you need to increment a counter of invalid lines in the catch
section. It indicates that the line is wrong because the number is
not a number;
you need to increment a counter of invalid lines in an else section
of the if
if (elements.length == 4)
it means that you have too much or too many arguments;
you need to increment a counter of invalid lines if HomeTeam and
AwayTeam are =="" because you don't have the name of the team;
Cheers
You can add two counters - one for all (allCounter) and one for wrong lines (wrongCounter):
at the beginning of every loop iteration increment allCounter:
while (s.hasNext()) {
allCounter++;
line = s.nextLine(); // reads the next line from the file
...
if something is wrong, increment wrongCounter and continue to next iteration of loop
if (elements.length != 4) {
++wrongCounter;
continue; //breaks this iteration and moves to next one
}
//otherwise proceed normally
homeTeam = elements[0].trim(); // trims home team
awayTeam = elements[1].trim(); // trims away team
...
Similarly in second if and catch clause:
catch (NumberFormatException e) {
++wrongCounter;
}
And of course:
int correctCounter = allCounter - wrongCounter;
One more thing: By Java convention you should write all variable/method names with camelCase, i.e start with small letter and then start every new word with capital letter:
Example: not HomeTeam, but homeTeam
Related
i have an assignment (Java using Netbeans to input Club Name, Input Score, and then Print the table-like league standings.
Each line displays the outcome of our input, and show the standings like it should (CLUB Name with biggest point is on top of the table:
Here's what i mean: (user input in BOLD)
Input No. of Clubs : 4
Input club 1 : ManUtd
Input club 2 : Liverpool
Input club 3 : Chelsea
Input club 4 : Arsenal
Input Score:
ManUtd x Liverpool : 1 1
ManUtd x Chelsea : 1 0
ManUtd x Arsenal: 1 0
Liverpool x Chelsea : 1 1
Liverpool x Arsenal : 1 0
Chelsea x Arsenal : 1 1
and displays the output of team records like this :
Team Played Win Draw Lose Pts
Manutd 3 2 1 0 7
Liverpool 3 1 2 0 5
Chelsea 3 0 2 1 2
Arsenal 3 0 1 2 1
++++++++++++++++++++++++++++++++++++++++++++++
I have tried to connect the whole knowledge that I have ever read from the textbook but it's not working good. But don't know how to use the array, looping function, integer/data from that input .I cannot really realise the hint that can guide me to the solution. Anyone can help me please? I have just learned java by myself and COVID-19 makes studies difficult to meet up to my lecturer.
For anyone who reply this, thanks for the help :)
my basic code stuck in here:
package standings;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class LeagueStandings {
public static void main(String[] args) {
BufferedReader input = new BufferedReader(new
InputStreamReader(System.in));
int data = 0;
String[] nama = new String[30];
System.out.println("CLUB NAME");
System.out.println("+===============INPUTAN============================+");
try{
System.out.println("How Many Clubs ? = ");
data = Integer.parseInt(input.readLine());
for (int a=1;a<=data;a++){
System.out.println("------Club No."+ a +"------");
System.out.println("Enter club name = ");
nama[a] = input.readLine();
}
} catch (IOException e ){
System.out.println("Error");
}
}
The result expected like this (result expected from the lecturer)
Here is the solution to your problem. I tried to write as naive solution as possible as you are a beginner.
package com.standings;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class LeagueStandings {
public static void main(String[] args) {
try {
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
int data = 0;
System.out.print("Input number of clubs:\t");
data = Integer.parseInt(input.readLine());
String[] teamList = new String[data];
for (int i = 0; i < data; i++) {
System.out.print("Enter club " + (i + 1) + " :\t");
teamList[i] = input.readLine();
}
System.out.println("-------------------------------------------------");
// representing 2D array of team score board where each scoreBoard is of type
// 0 1 2 3 4
// [played] [win] [draw] [loose] [points]
int[][] scoreBoard = new int[data][5];
for (int i = 0; i < data - 1; i++) {
for (int j = i + 1; j < data; j++) {
System.out.print(teamList[i] + " X " + teamList[j] + " : ");
String score = input.readLine();
List<String> scoreList = new ArrayList<String>(Arrays.asList(score.split(" ")));
scoreList.removeIf(s -> s.equals(""));
int teamAScore = Integer.parseInt(scoreList.get(0));
int teamBScore = Integer.parseInt(scoreList.get(1));
scoreBoard[i][0]++;
scoreBoard[j][0]++;
if (teamAScore > teamBScore) {
scoreBoard[i][1]++;
scoreBoard[j][3]++;
scoreBoard[i][4] += 3;
} else if (teamAScore == teamBScore) {
scoreBoard[i][2]++;
scoreBoard[j][2]++;
scoreBoard[i][4]++;
scoreBoard[j][4]++;
} else {
scoreBoard[i][3]++;
scoreBoard[j][1]++;
scoreBoard[j][4] += 3;
}
}
}
System.out.format("%15s%15s%15s%15s%15s%15s\n", "TEAMS", "PLAYED", "WIN", "DRAW", "LOOSE", "POINTS");
for (int i = 0; i < data; i++) {
System.out.format("%15s", teamList[i]);
System.out.format("%15d%15d%15d%15d%15d\n", scoreBoard[i][0], scoreBoard[i][1], scoreBoard[i][2], scoreBoard[i][3], scoreBoard[i][4]);
}
} catch (IOException e) {
System.out.println("Error");
}
}
}
I need load file .txt with strings and int.
When it is loaded, the program prints the sum of ASCII values that was calculated using a method (I wrote already). My problem is sum all The strings and int.
It necessary to sum all rows, except the last line that shows the sum in ASCII.
NOTICE: There is 2 groups (colors) with same info
This the file. In yellow is the sum of all the info in .txt
My code:
System.out.println("Enter Path To File:");
File fileName = new File("Game.txt");
Scanner sFromFile = new Scanner(fileName);
String size = sFromFile.nextLine();
int sizeBoard = Integer.parseInt(size);System.out.println("Board size loading size= "+size+"X"+size);
String team = sFromFile.next();
// int numOfSoliders = sFromFile.nextInt();
Point arrSol []= new Point[sizeBoard];for(
int i = 0;i<arrSol.length;i++)
{
arrSol[i] = new Point(sFromFile);
System.out.println("Solider created successfully!");
}
// int numOfDragon = sFromFile.nextInt();
Point arrDragon[] = new Point[sizeBoard];for(
int i = 0;i<arrDragon.length;i++)
{
arrDragon[i] = new Point(sFromFile);
System.out.println("Dragon created successfully!");
}
// ALSO DID THE SAME TO OTHER GROUP...
// THE LAST LINE READING INPUT
int fileHashCode = sFromFile.nextInt();System.out.println("HashCode loading...\n Loaded hashCode= "+fileHashCode);
// TRY USE STRING METHOD
// while (sFromFile.hasNext()) {
// String str = sFromFile.nextLine();
// System.out.print(str + ". ");
// }
sFromFile.close();
// ALSO TRY OUTSIDE METHOD
public static String readFile(String fName) throws FileNotFoundException {
File f = new File(fName);
Scanner sFromFile = new Scanner(f);
for (int i = 0; i < board.length; i++) {
while (sFromFile.hasNext()) {
String str= sFromFile.nextLine();
String sum+=str;
// System.out.print(str + ". ");
}
}
sFromFile.close();
return sum;
}
It means to sum all characters (except line breaks) of the first 7 lines of text.
Proof
String input = "8\r\n" +
"RED\r\n" +
"8 0 0 0 1 0 2 0 3 0 4 0 5 0 6 0 7\r\n" +
"8 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7\r\n" +
"BLUE\r\n" +
"8 7 0 7 1 7 2 7 3 7 4 7 5 7 6 7 7\r\n" +
"8 6 0 6 1 6 2 6 3 6 4 6 5 6 6 6 7\r\n" +
"6139";
try (Scanner sc = new Scanner(input)) {
int sum = 0;
for (int i = 0; i < 7; i++)
sum += sc.nextLine().chars().sum();
System.out.println("Calculated: " + sum);
System.out.println("Last line : " + sc.nextLine());
}
Output
Calculated: 6139
Last line : 6139
My program takes user input to create a sport score table.
Its validation function prints "Invalid input" when the array "words" contains less than 4 elements
for (int i = 0; i < counter; i++) { // A loop to control the Array
String[] words = football_list[i].split(":"); // Splits the input into 4 strings
if (words.length != 4) { // If the length of the array elements does not equal 4 then print error message
System.out.println("Input was not valid");
When I enter an incorrect input FIRST, it then makes the rest of the following scores to be deemed equally incorrect even when they are correct - here is an example of what that looks like on the text console.
Home team : Away team : Home score : Away score
Leeds : Liverpool : 2 :
Home team : Away team : Home score : Away score
Leeds : Liverpool : 2 : 1
Home team : Away team : Home score : Away score
Leeds : Liverpool : 2 : 1
Home team : Away team : Home score : Away score
Leeds : Liverpool : 2 : 1
Home team : Away team : Home score : Away score
quit
Input was not valid
Input was not valid
Input was not valid
Input was not valid
Totals
------------------------- Total games played: 0*
END--
This is where I think the problem is:
for (int i = 0; i < counter; i++) {
String[] words = football_list[i].split(":"); 4 strings
if (words.length != 4) {
System.out.println("Input was not valid");
counter--;
i--;
} else {
System.out.println(words[0].trim() + " [" + words[2].trim() + "]" + " | " + words[1].trim() + " [" + words[3].trim() + "]"); // Formats and prints the output
System.out.println(" ");
System.out.println(" ");
System.out.println(" ");
System.out.println(" Totals ");
System.out.println("-------------------------");
System.out.println("Total games played: " + counter);
}
}
Don't decrement i inside the loop.
Because you decrement i and counter if input is invalid. And after that increase i in for-statement. In this case you are reading invalid row again and again while counter > i
To make things more readable and less error prone, you could simply use the length of your array to control your loop ending, and increment counter (starting at 0) only when the input is valid :
int counter = 0;
for (int i = 0; i < football_list.length; i++) { // A loop to control the Array
String[] words = football_list[i].split(":"); // Splits the input into 4 strings
if (words.length != 4) { // If the length of the array elements does not equal 4 then print error message
System.out.println("Input was not valid");
} else {
counter++;
System.out.println(words[0].trim() + " [" + words[2].trim() + "]" + " | " + words[1].trim() + " ["
+ words[3].trim() + "]"); // Formats and prints the output
}
}
I am working on a small project that takes user input (match results) on one line, splits the input and outputs the same data in a different format. I am struggling to find a way to output the data in a specific format. As well as total games played, I want my program to produce a chart like output in the format
home_name [home_score] | away_name [away_score]
This is the code I have at the minute which allows users to input results line after line in the following format
home_name : away_name : home_score : away_score
until they enter stop, which breaks the loop (and hopefully soon outputs the data).
import java.util.*;
public class results {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int totalGames = 0;
String input = null;
System.out.println("Please enter results in the following format"
+ " home_name : away_name : home_score : away_score"
+ ", or enter stop to quit");
while (null != (input = scan.nextLine())){
if ("stop".equals(input)){
break;
}
String results[] = input.split(" : ");
for (int x = 0; x < results.length; x++) {
}
totalGames++;
}
System.out.println("Total games played is " + totalGames);
}
}
You can see here.
You can format your text as you wish.
The general syntax is
%[arg_index$][flags][width][.precision]conversion char Argument
numbering starts with 1 (not 0). So to print the first argument, you
should use 1$ (if you are using explicit ordering).
You can use regEx to parse the line:
(\w)\s(\w)\s|\s(\w)\s(\w)
Base on Java code from (from http://tutorials.jenkov.com/java-regex/matcher.html)
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class MatcherFindStartEndExample{
public static void main(String[] args){
String text = "Belenenses 6 | Benfica 0";
String patternString = "(\\w+)\\s(\\w+)\\s\\|\\s(\\w+)\\s(\\w+)";
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(text);
while (matcher.find()){
System.out.println("found: " + matcher.group(1));
System.out.println("found: " + matcher.group(2));
System.out.println("found: " + matcher.group(3));
System.out.println("found: " + matcher.group(4));
}
}}
Use this code instead of your
String results[] = input.split(" : ");
for (int x = 0; x < results.length; x++) {
}
You should do things in two times :
1) retrieving information entered by the user and storing it in instances of a custom class : PlayerResult.
2) performing the output according to the expected format. You should also compute the max size of each column before creating the graphical table.
Otherwise you could have a ugly rendering.
First step :
List<PlayerResult> playerResults = new ArrayList<PlayerResult>();
...
String[4] results = input.split(" : ");
playerResults.add(new PlayerResult(results[0],results[1],results[2],results[3])
Second step :
// compute length of column
int[] lengthByColumn = computeLengthByColumn(results);
int lengthHomeColumn = lengthByColumn[0];
int lengthAwayColumn = lengthByColumn[1];
// render header
System.out.print(adjustLength("home_name [home_score]", lengthHomeColumn));
System.out.println(adjustLength("away_name [away_score]", lengthAwayColumn));
// render data
for (PlayerResult playerResult : playerResults){
System.out.print(adjustLength(playerResult.getHomeName() + "[" + playerResult.getHomeName() + "]", lengthHomeColumn));
System.out.println(adjustLength(playerResult.getAwayName() + "[" + playerResult.getAwayScore() + "]", lengthAwayColumn));
}
You can keep the games statistics by adding results array values to the finalResults ArrayList. And then outputting its results as stop input is entered.
For counting the total results per team HashMap<String, Integer> is the best choice.
Here is the complete code with comments to make it clear:
import java.util.*;
// following the naming conventions class name must start with a capital letter
public class Results {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int totalGames = 0;
String input;
System.out.println("Please enter results in the following format: \n"
+ "'HOME_NAME : AWAY_NAME : HOME_SCORE : AWAY_SCORE' \n"
+ "or enter 'stop' to quit");
// HashMap to keep team name as a key and its total score as value
Map<String, Integer> scoreMap = new HashMap<>();
// ArrayList for storing game history
List<String> finalResults = new ArrayList<>();
// don't compare null to value. Read more http://stackoverflow.com/questions/6883646/obj-null-vs-null-obj
while ((input = scan.nextLine()) != null) {
if (input.equalsIgnoreCase("stop")) { // 'Stop', 'STOP' and 'stop' are all OK
scan.close(); // close Scanner object
break;
}
String[] results = input.split(" : ");
// add result as String.format. Read more https://examples.javacodegeeks.com/core-java/lang/string/java-string-format-example/
finalResults.add(String.format("%s [%s] | %s [%s]", results[0], results[2], results[1], results[3]));
// check if the map already contains the team
// results[0] and results[1] are team names, results[2] and results[3] are their scores
for (int i = 0; i < 2; i++) {
// here is used the Ternary operator. Read more http://alvinalexander.com/java/edu/pj/pj010018
scoreMap.put(results[i], !scoreMap.containsKey(results[i]) ?
Integer.valueOf(results[i + 2]) :
Integer.valueOf(scoreMap.get(results[i]) + Integer.valueOf(results[i + 2])));
}
totalGames++; // increment totalGames
}
System.out.printf("%nTotal games played: %d.%n", totalGames); // output the total played games
// output the games statistics from ArrayList finalResults
for (String finalResult : finalResults) {
System.out.println(finalResult);
}
// output the score table from HashMap scoreMap
System.out.println("\nScore table:");
for (Map.Entry<String, Integer> score : scoreMap.entrySet()) {
System.out.println(score.getKey() + " : " + score.getValue());
}
}
}
Now testing with input:
team1 : team2 : 1 : 0
team3 : team1 : 3 : 2
team3 : team2 : 2 : 2
sToP
The output is:
Total games played: 3.
team1 [1] | team2 [0]
team3 [3] | team1 [2]
team3 [2] | team2 [2]
Score table:
team3 : 5
team1 : 3
team2 : 2
This is my input file:
0 I 4325 <4214, 6> <4718, 9> <1203, 11>
18 L 4214 12 <4325, 6> <4718, 5> <1483, 9>
35 F 4109
I am trying to write a method that will read in the first column, second column (either I, L or F) and store all the pairs in each row e.g., (4214, 6), (4718, 9). What I've done is used the delimiter from the scanner class to get rid of '<', ',' and '>', and it does but when I try calling temp.next(), I keep on getting an error. My code is below (sometime the error goes away when I use skip(" "):
public void parseFile(Scanner input) {
int prevSeqNo = -1;
while (input.hasNextLine()) {
String line = input.nextLine();
if (!line.startsWith("#") && !line.isEmpty()) { // ignore comments
// and blank lines
Scanner temp = new Scanner(line).useDelimiter("<|,| |>"); // ignore all '<', ',' and '>'
// while(temp.hasNext())
// System.out.print(" " + temp.next() );
// System.out.println();
int timeStamp = temp.nextInt();
System.out.println("Timestamp: " + timeStamp);
temp.skip(" ");
String event = temp.next();
System.out.println("Event: " + event);
if (event.equals("I")) {
temp.skip(" ");
startNode = temp.nextInt();
System.out.println("starting node: " + startNode);
// while (temp.hasNext()) {
temp.skip(" ");
int node = temp.nextInt();
System.out.println(node);
temp.skip("");
int weight = temp.nextInt();
System.out.println(weight);
// System.out.println("<" + node + ", " + weight + ">");
// }
} else if (event.equals("L")) {
int currSeqNo = temp.nextInt();
System.out.println("Sequence number: " + currSeqNo); // discard if LSP has smaller or equal sequence number to max seen so far
if (currSeqNo >= prevSeqNo) {
prevSeqNo = currSeqNo; // update the previous sequence
// number
} else { // else if event == "F"
}
}
}
}
input.close();
}
After removing symbols:
0 I 4325 4214 6 4718 9 1203 11
18 L 4214 12 4325 6 4718 5 1483 9
29 L 4109 78 4718 3 1483 2
35 F 4109
Here is the error message:
Timestamp: 0
Event: I
starting node: 4325
4214
java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:864)
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextInt(Scanner.java:2117)
at java.util.Scanner.nextInt(Scanner.java:2076)
at LinkedStateRouting.parseFile(LinkedStateRouting.java:41)
at LinkedStateRouting.main(LinkedStateRouting.java:88)