JAVA- Read integers from txt file and compute integers - java

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

Related

Java - moving first letter of string to the end, and determining if word is the same when spelled backwards

I'm trying to make a program that when a user inputs a string using scanner, the first letter gets moved to the end of the word, and then the word is spelled backwards. The program then determines if you get the original word.
e.g if user types in 'potato' the program will move 'p' to the end, and will display true, as we get the same word backwards - 'otatop'.
Example output:
You have entered "BANANA".
Is ANANAB same as BANANA? True.
Thank you in advance for any help.
Jack
This is what I've got so far, but I don't think it works properly.
public class WordPlay {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String word;
String palindrome = "";
String quit = "quit";
do {
System.out.print("Enter a word: ");
word = scanner.nextLine().toUpperCase();
int length = word.length();
for (int i = length - 1; i >= 0; i--) {
palindrome = palindrome + word.charAt(i);
}
if (word.equals(palindrome)) {
System.out.println("Is the word + palindrome + " same as " + word + "?", true);
} else {
System.out.println(false);
}
} while (!word.equals(quit));
System.out.println("Good Bye");
scanner.close();
}
}
Here it is.
public static void main(String[] args) {
// To take input.
Scanner scan = new Scanner(System.in);
System.out.print("Enter Word: ");
String word = scan.next(); // taking the word from user
// moving first letter to the end.
String newWord = word.substring(1) + word.charAt(0);
// reversing the newWord.
String reversed = new StringBuffer(newWord).reverse().toString();
// printing output.
System.out.println("You have entered '"+word+"'. "
+ "Is "+newWord+" same as "+word+"? "
+reversed.equals(word)+".");
// closing the input stream.
scan.close();
}
This works:
import java.util.*;
public class HelloWorld{
public static void main(String []args){
Scanner scan = new Scanner(System.in);
String s1 = scan.next();
char s2 = s1.charAt(0);
String s3 = s1.substring(1) + s2;
s3 = new StringBuilder(s3).reverse().toString();
if(s1.equals(s3))
System.out.println("They are same");
else
System.out.println("They are not the same");
}
}
This is very simple with some of observation. Your question is you have to move the first latter to the end and check reverse if the new string is same or not.
My ovservation:
For BANANA new string is ANANAB. Now reverse the string and check weather it is same as the first one.
Now If you ignore the first char B the string will be ANANA. As you have to reverse the string and check this one is same as the first one so this is like palindrome problem. For the input BANANA ANANA is palindrome. We are moving the first char to the end so there is no impact of it on checking palindrome. So I ignore the first char and check the rest is palindrome or not.
The Method is like:
private static boolean getAns(String word) {
int st = 1;
int en = word.length() - 1;
while (st < en) {
if (word.charAt(en) != word.charAt(st)) {
return false;
}
st++;
en--;
}
return true;
}
The main function is:
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Input your String:");
String word = scanner.nextLine();
boolean ans = getAns(word);
System.out.println("You have entered " + word + ". Is " + word.substring(1) + word.charAt(0) + " same as " + word + "? : " + ans + ".");
}
The Runtime for this problem is n/2 means O(n) and no extra memory and space needed,
I have tried to code it. See if it helps
import java.util.Scanner;
class StringCheck
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
String str = new String();
String tempstr = new String();
System.out.println("Enter your String ");
str = sc.next();
int len = str.length();
//putting first character of str at last of tempstr
for (int i = 1 ; i<len; i++)
{
tempstr += str.charAt(i);
}
tempstr += str.charAt(0);
//reversing tempstr
char[] tempchar = tempstr.toCharArray();
int j = len-1;
char temp;
for ( int i = 0; i<len/2 ; i++)
{
if(i<j)
{
temp = tempchar[i];
tempchar[i] = tempchar[j];
tempchar[j]= temp;
j--;
}
else
break;
}
//reversing completed
tempstr = new String(tempchar);
// System.out.println("the reversed string is "+tempstr);
if(str.compareTo(tempstr)==0)
{
System.out.println("true");
}
else
{
System.out.println("false");
}
}
}

Asking for a word and checking its number of occurrence in a text file

public class Try{
public static void main (String args[]) throws IOException {
BufferedReader in = new BufferedReader(new FileReader("Try.txt"));
Scanner sc = new Scanner(System.in);
System.out.print("Enter the subtring to look for: ");
String Word=sc.next();
String line=in.readLine();
int count =0;
String s[];
do
{
s=line.split(" ");
for(int i=0; i < s.length; i++)
{
String a = s[i];
if(a.contains(Word))
count++;
}
line=in.readLine();
}while(line!=null);
System.out.print("There are " +count+ " occurences of " +Word+ " in ");
java.io.File file = new java.io.File("Try.txt");
Scanner input = new Scanner(file);
while(input.hasNext())
{
String word = input.nextLine();
System.out.print(word);
}
}
}
The intended purpose of my program is to ask the user for a certain word(s) that will be checked in a text file and if it exists, it will count the number of times the user-entered word occurs in the text file. So far, my program can only search for one word. If I try two words separated by space, only the first word will be searched and counted for its number of occurrence. Any tips on how to search multiple words?
I was following literally the title of the question and therefore I will suggest this algorithm:
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new FileReader("Test.txt"));
Scanner sc = new Scanner(System.in);
System.out.print("Enter the subtring to look for: ");
String word = sc.next();
String line = in.readLine();
int count = 0;
// here is where the efficiently magic happens
do {
// 1. you dont need to split a line by spaces, too much overhead...
// 2. and you dont need to do counter++
// 3. do instead: calculate the number of coincidences that the word is
//repeated in a whole line...that is what the line below does..
count += (line.length() - line.replace(word, "").length()) / word.length();
//the rest looks fine
//NOTE: if you need a whole word then wrap the input of the user and add the empty spaces at begin and at the end...so the match will be perfect to a word
line = in.readLine();
} while (line != null);
System.out.print("There are " + count + " occurences of " + word + " in ");
}
Edit:
if you want to check more than one word in the document then use this
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new FileReader("Test.txt"));
Scanner sc = new Scanner(System.in);
System.out.print("Enter the subtring to look for: ");
String input = sc.nextLine();
String[] word = input.split(" ");
String line = in.readLine();
int count = 0;
do {
for (String string : word) {
count += (line.length() - line.replace(string, "").length()) / string.length();
}
line = in.readLine();
} while (line != null);
System.out.print("There are " + count + " occurences of " + Arrays.toString(word) + " in ");
}

How to Extract Multiple words from a string using IndexOf and substring Java?

I have a file i imported through system, Now i am stuck. Using while loops and if statements, and WITHOUT the help of the Split() method, How could i first, Read the file, line by line with the scanner? Then second how could i pull the words out one by one, As i pull out one word, A variable, countWords has to increase by one, say there is 5 words in a string, I would need to run through the loop 5 times and countWords would become 5.
This is the code i have so far, Kind of crappy.
import java.util.Scanner;
import java.io.*;
class Assignmentfive
{
private static final String String = null;
public static void main(String[] args) throws FileNotFoundException
{
Scanner scan = new Scanner(new File("asgn5data.txt"));
int educationLevel = 0;
String fileRead = "";
int wordCount = 0;
while (scan.hasNext() && !fileRead.contains("."))
{
fileRead = scan.nextLine();
int index = fileRead.indexOf(" ");
String strA = fileRead.substring(index);
System.out.print(strA);
wordCount++;
}
There is more to my code, however it is just a few calculations commented out.
Thanks!
Here is how I would refactor your while loop to correctly extract, print, and count all words in a sentence:
while (scan.hasNext()) {
int wordCount = 0;
int numChars = 0;
fileRead = scan.nextLine();
// Note: I add an extra space at the end of the input sentence
// so that the while loop will pick up on the last word.
if (fileRead.charAt(fileRead.length() - 1) == '.') {
fileRead = fileRead.substring(0, fileRead.length() - 1) + " ";
}
else {
fileRead = fileRead + " ";
}
int index = fileRead.indexOf(" ");
do {
String strA = fileRead.substring(0, index);
System.out.print(strA + " ");
fileRead = fileRead.substring(index+1, fileRead.length());
index = fileRead.indexOf(" ");
wordCount++;
numChars += strA.length();
} while (index != -1);
// here is your computation.
if (wordCount > 0) {
double result = (double)numChars / wordCount; // average length of words
result = Math.pow(result, 2.0); // square the average
result = wordCount * result; // multiply by number of words
System.out.println(result); // output this number
}
}
I tested this code by hard-coding the string fileRead to be your first sentence The cat is black.. I got the following output.
Output:
The
cat
is
black

How to count the amount of times a word shows up in text file in Java?

So I'm pretty new to Java and I'm working on a code that is supposed to read a .txt file that the user inputs and then ask the user for a word to search for within the .txt file. I'm having trouble figuring out how to count the amount of times the inputted word shows up in the .txt file. Instead, the code I have is only counting the amount of lines the code shows up in. Can anyone help me figure out what to do to have my program count the amount of times the word shows up instead of the amount of lines the word shows up in? Thank you! Here's the code:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class TextSearch {
public static void main(String[] args) throws FileNotFoundException {
Scanner txt;
File file = null;
String Default = "/eng/home/tylorkun/workspace/09.1/src/Sample.txt";
try {
txt = new Scanner(System.in);
System.out.print("Please enter the text file name or type 'Default' for a default file. ");
file = new File(txt.nextLine());
txt = new Scanner(file);
while (txt.hasNextLine()) {
String line = txt.nextLine();
System.out.println(line);
}
txt.close();
} catch (Exception ex) {
ex.printStackTrace();
}
try {
txt = new Scanner(file);
Scanner in = new Scanner(System.in);
in.nextLine();
System.out.print("Please enter a string to search for. Please do not enter a string longer than 16 characters. ");
String wordInput = in.nextLine();
//If too long
if (wordInput.length() > 16) {
System.out.println("Please do not enter a string longer than 16 characters. Try again. ");
wordInput = in.nextLine();
}
//Search
int count = 0;
while (txt.hasNextLine()) //Should txt be in?
{
String line = txt.nextLine();
count++;
if (line.contains(wordInput)) //count > 0
{
System.out.println("'" + wordInput + "' was found " + count + " times in this document. ");
break;
}
//else
//{
// System.out.println("Word was not found. ");
//}
}
} catch (FileNotFoundException e) {
System.out.println("Word was not found. ");
}
} //main ends
} //TextSearch ends
Since the word doesn't have to be standalone, you can do an interesting for loop to count how many times your word appears in each line.
public static void main(String[] args) throws Exception {
String wordToSearch = "the";
String data = "the their father them therefore then";
int count = 0;
for (int index = data.indexOf(wordToSearch);
index != -1;
index = data.indexOf(wordToSearch, index + 1)) {
count++;
}
System.out.println(count);
}
Results:
6
So the searching segment of your code could look like:
//Search
int count = 0;
while (txt.hasNextLine())
{
String line = txt.nextLine();
for (int index = line.indexOf(wordInput);
index != -1;
index = line.indexOf(wordInput, index + 1)) {
count++;
}
}
System.out.println(count);
Your problem is that you are incrementing count on each line, regardless of whether the word is present. Also, you have no code to count multiple matches per line.
Instead, use a regex search to find the matches, and increment count for each match found:
//Search
int count = 0;
Pattern = Pattern.compile(wordInput, Pattern.LITERAL | Pattern.CASE_INSENSITIVE);
while(txt.hasNextLine()){
Matcher m = pattern.matcher(txt.nextLine());
// Loop through all matches
while (m.find()) {
count++;
}
}
NOTE: Not sure what you are using this for, but if you just need the functionality you can combine the grep and wc (wordcount) command-line utilities. See this SO Answer for how to do that.

How do I achieve the following results using the PrinterWriter class from a text file?

My application here prompts the user for a text file, mixed.txt which contains
12.2 Andrew
22 Simon
Sophie 33.33
10 Fred
21.21 Hank
Candice 12.2222
Next, the application is to PrintWrite to all text files namely result.txt and errorlog.txt. Each line from mixed.txt should begin with a number first followed by a name. However, certain lines may contain the other way round meaning to say name then followed by a number. Those which begins with a number shall be added to a sum variable and written to the result.txt file while those lines which begin with the name along with the number shall be written to the errorlog.txt file.
Therefore, on the MS-DOS console the results are as follow:
type result.txt
Total: 65.41
type errorlog.txt
Error at line 3 - Sophie 33.33
Error at line 6 - Candice 12.2222
Ok here's my problem. I only managed to get up to the stage whereby I have had all numbers added to result.txt and names to errorlog.txt files and I have no idea how to continue from there onwards. So could you guys give me some advice or help on how to achieve the results I need?
Below will be my code:
import java.util.*;
import java.io.*;
class FileReadingExercise3 {
public static void main(String[] args) throws FileNotFoundException
{
Scanner userInput = new Scanner(System.in);
Scanner fileInput = null;
String a = null;
int sum = 0;
do {
try
{
System.out.println("Please enter the name of a file or type QUIT to finish");
a = userInput.nextLine();
if (a.equals("QUIT"))
{
System.exit(0);
}
fileInput = new Scanner(new File(a));
}
catch (FileNotFoundException e)
{
System.out.println("Error " + a + " does not exist.");
}
} while (fileInput == null);
PrintWriter output = null;
PrintWriter output2 = null;
try
{
output = new PrintWriter(new File("result.txt")); //writes all double values to the file
output2 = new PrintWriter(new File("errorlog.txt")); //writes all string values to the file
}
catch (IOException g)
{
System.out.println("Error");
System.exit(0);
}
while (fileInput.hasNext())
{
if (fileInput.hasNextDouble())
{
double num = fileInput.nextDouble();
String str = Double.toString(num);
output.println(str);
} else
{
output2.println(fileInput.next());
fileInput.next();
}
}
fileInput.close();
output.close();
output2.close();
}
}
This is the screenshot of the mixed.txt file:
You can change your while loop like this:
int lineNumber = 1;
while (fileInput.hasNextLine()) {
String line = fileInput.nextLine();
String[] data = line.split(" ");
try {
sum+= Double.valueOf(data[0]);
} catch (Exception ex) {
output2.println("Error at line "+lineNumber+ " - "+line);
}
lineNumber++;
}
output.println("Total: "+sum);
Here you can go through each line of the mixed.txt and check if it starts with a double or not. If it is double you can just add it to sum or else you can add the String to errorlog.txt. Finaly you can add the sum to result.txt
you should accumulate the result and after the loop write the summation, also you can count the lines for error using normal counter variable. for example:
double mSums =0d;
int lineCount = 1;
while (fileInput.hasNext())
{
String line = fileInput.nextLine();
String part1 = line.split(" ")[0];
if ( isNumeric(part1) ) {
mSums += Double.valueOf(part1);
}
else {
output2.println("Error at line " + lineCount + " - " + line);
}
lineCount++;
}
output.println("Totals: " + mSums);
// one way to know if this string is number or not
// http://stackoverflow.com/questions/1102891/how-to-check-if-a-string-is-a-numeric-type-in-java
public static boolean isNumeric(String str)
{
try
{
double d = Double.parseDouble(str);
}
catch(NumberFormatException nfe)
{
return false;
}
return true;
}
this will give you the result you want in error files:
Error at line 3 - Sophie 33.33
Error at line 6 - Candice 12.2222

Categories