i have an input that consists of any 2 numbers on a single line and there can be an unlimited number of lines, ex.
30 60
81 22
38 18
I want to split each line into 2 tokens, first token is the number on the left and the second token is the number on the right. What should i do? All help is appreciated.
With Scanner and System.in:
public class SplitTest
{
public static void main (final String[] args)
{
try (Scanner in = new Scanner (System.in))
{
while (in.hasNext ())
{
System.out.println ("Part 1: " + in.nextDouble ());
if (in.hasNext ())
System.out.println ("Part 2: " + in.nextDouble ());
}
}
catch (final Throwable t)
{
t.printStackTrace ();
}
}
}
If the input is always setup like that, take a look into String.split()
// For just splitting into two strings separated by whitespace
String numString = "30 60";
String[] split = numString.split("\\s+");
// For converting the strings to integers
int[] splitInt = new int[split.length];
for(int i = 0; i < split.length; i++)
splitInt[i] = Integer.parseInt(split[i]);
Related
I need some help with the code below.
What I'm trying to do is to write a program that reads in the file and computes the average grade and prints it out. I've tried several methods, like parsing the text file into parallel arrays, but I run into the problem of having the % character at the end of the grades. The program below is meant to add integers up too but the output is "No numbers found."
This is a clip of the text file (the whole file is 14 lines of similar input):
Arthur Albert,74%
Melissa Hay,72%
William Jones,85%
Rachel Lee,68%
Joshua Planner,75%
Jennifer Ranger,76%
This is what I have so far:
final static String filename = "filesrc.txt";
public static void main(String[] args) throws IOException {
Scanner scan = null;
File f = new File(filename);
try {
scan = new Scanner(f);
} catch (FileNotFoundException e) {
System.out.println("File not found.");
System.exit(0);
}
int total = 0;
boolean foundInts = false; //flag to see if there are any integers
while (scan.hasNextLine()) { //Note change
String currentLine = scan.nextLine();
//split into words
String words[] = currentLine.split(" ");
//For each word in the line
for(String str : words) {
try {
int num = Integer.parseInt(str);
total += num;
foundInts = true;
System.out.println("Found: " + num);
}catch(NumberFormatException nfe) { }; //word is not an integer, do nothing
}
} //end while
if(!foundInts)
System.out.println("No numbers found.");
else
System.out.println("Total: " + total);
// close the scanner
scan.close();
}
}
Any help would be much appreciated!
Here's the fixed code. Instead of splitting the input using
" "
you should have split it using
","
That way when you parse the split strings you can use the substring method and parse the number portion of the input.
For example, given the string
Arthur Albert,74%
my code will split it into Arthur ALbert and 74%.
Then I can use the substring method and parse the first two characters of 74%, which will give me 74.
I wrote the code in a way so that it can handle any number between 0 and 999, and added comments when I made additions that you didn't already have. If you still have any questions however, don't be afraid to ask.
final static String filename = "filesrc.txt";
public static void main(String[] args) throws IOException {
Scanner scan = null;
File f = new File(filename);
try {
scan = new Scanner(f);
} catch (FileNotFoundException e) {
System.out.println("File not found.");
System.exit(0);
}
int total = 0;
boolean foundInts = false; //flag to see if there are any integers
int successful = 0; // I did this to keep track of the number of times
//a grade is found so I can divide the sum by the number to get the average
while (scan.hasNextLine()) { //Note change
String currentLine = scan.nextLine();
//split into words
String words[] = currentLine.split(",");
//For each word in the line
for(String str : words) {
System.out.println(str);
try {
int num = 0;
//Checks if a grade is between 0 and 9, inclusive
if(str.charAt(1) == '%') {
num = Integer.parseInt(str.substring(0,1));
successful++;
total += num;
foundInts = true;
System.out.println("Found: " + num);
}
//Checks if a grade is between 10 and 99, inclusive
else if(str.charAt(2) == '%') {
num = Integer.parseInt(str.substring(0,2));
successful++;
total += num;
foundInts = true;
System.out.println("Found: " + num);
}
//Checks if a grade is 100 or above, inclusive(obviously not above 999)
else if(str.charAt(3) == '%') {
num = Integer.parseInt(str.substring(0,3));
successful++;
total += num;
foundInts = true;
System.out.println("Found: " + num);
}
}catch(NumberFormatException nfe) { }; //word is not an integer, do nothing
}
} //end while
if(!foundInts)
System.out.println("No numbers found.");
else
System.out.println("Total: " + total/successful);
// close the scanner
scan.close();
}
Regex: ^(?<name>[^,]+),(?<score>[^%]+)
Details:
^ Asserts position at start of a line
(?<>) Named Capture Group
[^] Match a single character not present in the list
+ Matches between one and unlimited times
Java code:
import java.util.regex.Pattern;
import java.util.regex.Matcher;
final static String filename = "C:\\text.txt";
public static void main(String[] args) throws IOException
{
String text = new Scanner(new File(filename)).useDelimiter("\\A").next();
final Matcher matches = Pattern.compile("^(?<name>[^,]+),(?<score>[^%]+)").matcher(text);
int sum = 0;
int count = 0;
while (matches.find()) {
sum += Integer.parseInt(matches.group("score"));
count++;
}
System.out.println(String.format("Average: %s%%", sum / count));
}
Output:
Avarege: 74%
If you have a small number of lines that adhere to the format you specified, you can try this (IMO) nice functional solution:
double avg = Files.readAllLines(new File(filename).toPath())
.stream()
.map(s -> s.trim().split(",")[1]) // get the percentage
.map(s -> s.substring(0, s.length() - 1)) // strip off the '%' char at the end
.mapToInt(Integer::valueOf)
.average()
.orElseThrow(() -> new RuntimeException("Empty integer stream!"));
System.out.format("Average is %.2f", avg);
Your split method is wrong, and you didn't use any Pattern and Matcher to get the int values. Here's a working example:
private final static String filename = "marks.txt";
public static void main(String[] args) {
// Init an int to store the values.
int total = 0;
// try-for method!
try (BufferedReader reader = Files.newBufferedReader(Paths.get(filename))) {
// Read line by line until there is no line to read.
String line = null;
while ((line = reader.readLine()) != null) {
// Get the numbers only uisng regex
int getNumber = Integer.parseInt(
line.replaceAll("[^0-9]", "").trim());
// Add up the total.
total += getNumber;
}
} catch (IOException e) {
System.out.println("File not found.");
e.printStackTrace();
}
// Print the total only, you know how to do the avg.
System.out.println(total);
}
You can change your code in the following way:
Matcher m;
int total = 0;
final String PATTERN = "(?<=,)\\d+(?=%)";
int count=0;
while (scan.hasNextLine()) { //Note change
String currentLine = scan.nextLine();
//split into words
m = Pattern.compile(PATTERN).matcher(currentLine);
while(m.find())
{
int num = Integer.parseInt(m.group());
total += num;
count++;
}
}
System.out.println("Total: " + total);
if(count>0)
System.out.println("Average: " + total/count + "%");
For your input, the output is
Total: 450
Average: 75%
Explanations:
I am using the following regex (?<=,)\\d+(?=%)n to extract numbers between the , and the % characters from each line.
Regex usage: https://regex101.com/r/t4yLzG/1
I'm trying to write a Java program to analyse each string in a string array from a text file and if the number parses to a double, the program prints the word previous to it and the word after. I can't seem to find out how to parse each element of a string array. Currently it will only print the first number and the following word but not the previous word. Hopefully somebody can help.
My text file is as follows:
Suppose 49 are slicing a cake to divide it between 5 people. I cut myself a big slice, consisting of 33.3 percent
of the whole cake. Now it is your turn to cut a slice of cake. Will you also cut a 33.3 percent slice? Or will you
be fairer and divide the remaining 66.6 percent of the cake into 4 even parts? How big a slice will you cut?
Here is my code:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
import javax.swing.JOptionPane;
public class NumberSearch {
public static void main(String args[]) throws FileNotFoundException {
//creating File instance to reference text file in Java
// String filedirect = JOptionPane.showInputDialog(null, "Enter your file");
File text = new File("cakeQuestion2.txt");
//Creating Scanner instance to read File in Java
Scanner scnr = new Scanner(text);
//Reading each line of file using Scanner class
int lineNumber = 1;
while(scnr.hasNextLine())
{
String line = scnr.nextLine();
lineNumber++;
//Finding words
String[] sp = line.split(" +"); // "+" for multiple spaces
for (int i = 1; i < sp.length; i++)
{
{
double d = Double.parseDouble(sp[i]);
// System.out.println(+ d);
if (isDouble(sp[i]))
{
// have to check for ArrayIndexOutOfBoundsException
String surr = (i-2 > 0 ? " " + sp[i-2]+" " : "") +
sp[i] +
(i+1 < sp.length ? " "+sp[i+1] : "");
System.out.println(surr);
}
}}
}
}
public static boolean isDouble( String str )
{
try{
Double.parseDouble( str );
return true;
}
catch( Exception e ){
return false;
}}}
Mmmmm... your code seems too verbose and complex for the mission.
Check this snippet:
public static void main(String args[]) throws FileNotFoundException {
String line = "Suppose 49 are slicing a cake to divide it between 5 people. I cut myself a big slice, consisting of 33.3 percent of the whole cake. Now it is your turn to cut a slice of cake. Will you also cut a 33.3 percent slice? Or will you be fairer and divide the remaining 66.6 percent of the cake into 4 even parts? How big a slice will you cut?";
String[] sp = line.split(" +"); // "+" for multiple spaces
final String SPACE = " ";
// loop over the data
for (int i = 0; i < sp.length; i++) {
try {
// if exception is not raised, IS A DOUBLE!
Double.parseDouble(sp[i]);
// if is not first position print previous word (avoid negative index)
if (i > 0)
System.out.print(sp[i - 1] + SPACE);
// print number itself
System.out.print(sp[i] + SPACE);
// if is not last position print previous word (avoid IOOBE)
if (i < sp.length - 1)
System.out.print(sp[i + 1]);
// next line!
System.out.println();
} catch (NumberFormatException ex) {
// if is not a number, not our problem!
}
}
}
RESULT:
Suppose 49 are
between 5 people.
of 33.3 percent
a 33.3 percent
remaining 66.6 percent
into 4 even
I need to do a simple program that counts the number of words and gives the total of the numbers in a text file. The program has to compute the sum and average of all the numbers. The average is the sum divided by the count.The file counts the numbers and words together. It just prints 34.
//CAT DOG BIRD FISH
//1 2 3 4 5
//TURTLE LIZARD SNAKE
//6 7 8 9 10
//FISH SHARK
//11 12 13 14 15
//SPIDER FLY GRASSHOPPER ANT SCORPION
//16 17 18 19 20
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Scanner;
import javax.swing.JOptionPane;
public class HomeWork8 {
public static void main(String[] args) throws IOException {
String words, numbers, message;
int numberWords = 0, countNumber = 0;
FileInputStream fis = new FileInputStream("/Users/ME/Documents/Words and Numbers.txt");
Scanner in = new Scanner(fis);
while (in.hasNext()) {
words = in.next();
numberWords++;
}
while (in.hasNext()) {
in.useDelimiter("");
numbers = in.next();
countNumber++;
}
in.close();
message = "The number of words read from the file was " + numberWords
+ "\nThe count of numbers read from the file was" + countNumber;
JOptionPane.showMessageDialog(null, message);
}
}
String pattern ="\\d";
String word="shdhdshk 46788 jikdjsk 9 dsd s90 dsds76";
Matcher m = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE).matcher(word);
int count=0;
while (m.find()) {
count++;
}
System.out.println(count);
If you need to get the single number character count you can use \d . But If you are interested in whole number occurrence then you have to use \d+ instead of \d. Ex: 46788,9,90,76
You can even use regular expressions to filter the words and numbers as is shown below:
public static void main(String[] args) throws IOException {
String words, message;
int numberWords = 0, countNumber = 0;
FileInputStream fis = new FileInputStream("src/WordsandNumbers.txt");
Scanner in = new Scanner(fis);
String numRegex = ".*[0-9].*";
String alphaRegex = ".*[A-Za-z].*";
while (in.hasNext()) {
words=in.next();
if (words.matches(alphaRegex)) {
numberWords++;
}
else if(words.matches(numRegex))
{
countNumber++;
}
}
in.close();
message = "The number of words read from the file was " + numberWords
+ "\nThe count of numbers read from the file was" + countNumber;
System.console().writer().println(message);
}
You need to have a single iteration through the content of the filerather than having 2 while loops.
Just before the second while (in.hasNext()) { you should reset the stream by adding the following code:
in = new Scanner(fis);
You should also revise your code for checking for numbers (I don't think you're checking for numbers anywhere).
I literally have to take a .java file and reverse the letters so e.g
"Hello world
1234 1233 123"
so its outputs in the file as:
"dlrow olleh
321 3321 4321"
Spaces and lines included.
My program does that kind of, it reverses everything but I cannot get it to format it in the lines
It output is either
d
l
r
o
w
....
or
dlrow olleh 321 3321 4321
Here is my program:
import java.io.*;
import java.util.*;
public class Reverse {
public static void main(String[] args) throws FileNotFoundException {
try {
File in = new File("C:\\Users\\Ceri\\workspace1\\HelloWorld\\src\\HelloWorld.java");
Scanner s = new Scanner( in );
PrintWriter out = new PrintWriter("C:\\Users\\Ceri\\workspace1\\HelloWorld\\src\\HelloWorld.txt");
while (s.hasNext()) {
String temp = s.nextLine();
for (int i = temp.length() - 1; i >= 0; i--) {
out.println(temp.charAt(i));
}
}
s.close();
out.close();
} catch (FileNotFoundException e) {
System.out.println("File not found");
}
}
}
Use print instead of println. Outside of your loop, you probably want a new line when your scanner reads a new line:
while (s.hasNext()) {
String temp = s.nextLine();
for (int i = temp.length() - 1; i >= 0; i--) {
out.print(temp.charAt(i));
}
out.println();
}
Here's the output I got:
321 3321 4321 dlrow olleH
...which is a little different than the output you show (which seems to split the letters from the numbers and reverse them separately), but reverses the string in its entirety just fine as you mentioned originally.
below is my code for a homework assignment where I need to read the contents of an external file and determine the number of words within it, number of 3-letter words, and percentage of total. I've got that part down just fine, but I also have to print the external file's contents prior to displaying the above information. Below is my current code:
public class Prog512h
{
public static void main( String[] args)
{
int countsOf3 = 0;
int countWords = 0;
DecimalFormat round = new DecimalFormat("##.00"); // will round final value to two decimal places
Scanner poem = null;
try
{
poem = new Scanner (new File("prog512h.dat.txt"));
}
catch (FileNotFoundException e)
{
System.out.println ("File not found!"); // returns error if file is not found
System.exit (0);
}
while (poem.hasNext())
{
String s = poem.nextLine();
String[] words = s.split(" ");
countWords += words.length;
for (int i = 0; i < words.length; i++)
{
countsOf3 += words[i].length() == 3 ? 1 : 0; // checks for 3-letter words
}
}
while(poem.hasNext())
{
System.out.println(poem.nextLine());
}
System.out.println();
System.out.println("Number of words: " + countWords);
System.out.println("Number of 3-letter words: " + countsOf3);
System.out.println("Percentage of total: " + round.format((double)((double)countsOf3 / (double)countWords) * 100.0)); // converts value to double and calculates percentage by dividing from total number of words
}
}
The statement
while(poem.hasNext())
{
System.out.println(poem.nextLine());
}
is supposed to print the external file's contents. However, it doesn't. When I try moving it before my prior while loop, it prints, but screws up my printed values for the # of words, 3-letter words, percentage, etc. I'm not really sure what the issue is here. Could someone provide some assistance?
Thank you in advance.
Your scanner is trying to reread the file but it is at the bottom so there are no more lines to read. You have two options:
Option 1
Create a new Scanner object for the same file (to start at the beginning again) and then call your while loop on that file (works, but not a great design).
Scanner poem2 = null;
try
{
poem2 = new Scanner (new File("prog512h.dat.txt"));
}
catch (FileNotFoundException e)
{
System.out.println ("File not found!"); // returns error if file is not found
System.exit (0);
}
while(poem2.hasNext())
{
System.out.println(poem2.nextLine());
}
Option 2
A better option would be to display each line as you read it in. This can be accomplished by adding an extra line to the already existent while loop:
while (poem.hasNext())
{
String s = poem.nextLine();
System.out.println(s); // <<< Display each line as you process it
String[] words = s.split(" ");
countWords += words.length;
for (int i = 0; i < words.length; i++)
{
countsOf3 += words[i].length() == 3 ? 1 : 0; // checks for 3-letter words
}
}
This only requires one Scanner object and only requires one read-through of the file which is much more efficient.