Counting numbers in a text file using Java - java

This has been troubling me for a while now. I normally don't tend to ask help and do my research, but I couldn't find an answer.
How do I write a program that reads a text file, and calculate how many times a certain number shows up?
I'm a huge beginner in Java, and also programming in general.
Here's my code.
This code generates a text file that has 100 random numbers
import java.io.*;
public class Rolling
{
public static void main (String[] args) throws IOException
{
int randomNum;
PrintWriter fileout = new PrintWriter (new FileWriter ("randumnums.txt"));
for (int i= 0; i < 101; i++)
{
randomNum = (int) (Math.random() * 100);
fileout.println (randomNum);
}
fileout.close();
}
}
Now the trouble I'm having is that I need to read the file and write a code saying X number was rolled 3 times. e.g the number 4 appeared 5 times in the text file, so I would need it to print "the number 4 was rolled 5 times".
import java.io.*;
public class Reading
{
public static void main (String[] args) throws IOException
{
BufferedReader readFile = new BufferedReader (new FileReader ("randumnums.txt"));
int number = 0;
int inMarks [] = new int [100];
for (int i = 0; i < 100; i++)
{
inMarks [i] = Integer.parseInt(readFile.readLine());
}
}
}

You're actually pretty close. It's clear that you're going to have to keep track of your counts in some kind of list, and an array will do quite nicely here.
First, after instantiating inMarks, initialize every value in it to 0:
int inMarks [] = new int [100];
for (int i = 0; i < 100; i++)
{
inMarks [i] = 0;
}
Then change the loop below to this:
String nextLine = null;
while ((nextLine = readFile.readLine()) != null)
{
int thisInt = Integer.parseInt(nextLine);
inMarks[thisInt] = inMarks[thisInt] + 1;
}
inMarks now perfectly tracks how many times each distinct int was rolled in the file. I'm going to let you implement the print-out part of the assignment, since that will give you a better understanding of how this solution works.

I have the feeling you are looking for something like this (I haven't tested this code)
import java.io.*;
public class Reading {
public static void main (String[] args) throws IOException {
BufferedReader readFile = new BufferedReader (new FileReader("randumnums.txt"));
int number = 0;
int inMarks [] = new int [100];
String readNumber = "";
while ((readNumber = readFile.readline()) != null) {
number = Integer.parseInt(readNumber);
inMarks[number]++;
}
}
}
The code above basically has an array of 100 integers. We then start reading the file until nothing can be read anymore. Everytime we read a line, we parse into an integer (which normally you should wrap around a try...catch). We then increase by 1 the number of times we have read this number by increasing the corresponding index in the array. So if you want to know how many times the number '32' appeared, you would do System.print.out(inMarks[32]);

Related

how do i detect a double line break in a data file

I have a data file that consists of a calorie count.
the calorie count it separated by each elf that owns it and how many calories are in each fruit.
so this represents 3 elves
4323
4004
4070
1780
5899
1912
2796
5743
3008
1703
4870
5048
2485
1204
30180
33734
19662
all the numbers next to each other are the same elf. the separated ones are seperate.
i tried to detect the double line break like so
import java.util.*;
import java.io.*;
public class Main
{
public static void main(String [] args) throws FileNotFoundException
{
int[] elf = new int[100000];
int cnt = 0;
Scanner input = new Scanner(new File("Elf.dat"));
while(input.hasNext())
{
elf[cnt] += input.nextInt();
if (input.next().equals("\n\n"));
{
cnt++;
}
}
int big = elf[0];
for (int lcv = 0; lcv < elf.length; lcv++)
{
if (big < elf[lcv])
{
big = elf[lcv];
}
}
System.out.println(big);
}
}
I'm trying this to detect the double line break
if (input.next().equals("\n\n"));
but its giving me errors. how would i detect it
Here is another alternative way to do this sort of thing. read comments in code:
public static void main(String[] args) throws FileNotFoundException {
List<Integer> elfSums; // Can grow dynamically whereas an Array can not.
int sum;
// 'Try With Resources' used here to auto close the reader and free resources.
try (Scanner input = new Scanner(new File("Elf.dat"))) {
elfSums = new ArrayList<>();
String line;
sum = 0;
while (input.hasNextLine()) {
line = input.nextLine();
if (line.trim().isEmpty()) {
elfSums.add(sum);
sum = 0; // Reset sum to 0 (new elf comming up)
}
// Does the line contain a string representation of a integer numerical value?
if (line.matches("\\d+")) {
// Yes...add to current sum value.
sum += Integer.parseInt(line);
}
}
}
if (sum > 0) {
elfSums.add(sum);
}
// Convert List to int[] Array (There are shorter ways to do this)
int[] elf = new int[elfSums.size()];
for (int i = 0; i < elfSums.size(); i++) {
elf[i] = elfSums.get(i);
// For the heck of it, display the total sum for this current Elf
System.out.println("Elf #" + (i+1) + " Sum: -> " + elf[i]);
}
/* The elf[] int array now holds the data you need WITHOUT
all those empty elements with the array. */
}
Welcome to Advent of Code 22.
As a good rule, never mix nextXXX methods with any other next.
To break up the Blocks you have 2 good options:
Read line by line and fill a new list when you encounter a empty/blank line
Read the whole text fully, then split by the \n\n Combination

How to read integers from one text file, sort them from least to greatest, and then write them to another text file

I am attempting to write 100 random integers to one text file, sort them from least to greatest, and then write those numbers, sorted, to a separate text file. I understand how to write the numbers to one file, and how to sort them. Both files must be created by the program if they do not already exist. For instance if the "Numbers.txt" that I write the original 100 random integers on does not exist, the program will create the file for me, as same goes for the text file I am attempting to write the sorted numbers on. I am struggling to understand how to write the sorted numbers from one file to another.
I have attempted to take the same numbers from the integer array that the numbers are originally stored in, and sort it with the Arrays.sort command, and then write that information to the separate file which I wish to be called "Sorted.txt". I run into a problem there where I get an incompatible type error, stating void cannot be converted to int, but do not know how to fix this error in logic.
import java.util.*;
import java.io.*;
public class Numbers {
public static void main(String[] args) throws Exception {
//check if source file exists
File number = new File("Numbers.txt");
File sorted = new File("Sorted.txt");
if (!number.exists()) {
try ( // create the file
PrintWriter output = new PrintWriter(number);
) {
for (int i = 0; i <= 100; i++) {
output.print(((int)(Math.random() * 999) + 1) + " ");
}
}
}
try (
Scanner input = new Scanner(number);
) {
int[] numbers = new int[100];
for (int i = 0; i < 100; i++)
System.out.print(numbers[i] + " ");
System.out.println();
if (!sorted.exists()) {
try (
PrintWriter output = new PrintWriter(sorted)
) {
for (int i = 0; i < 100; i ++) {
output.print((int)Arrays.sort(numbers));
}
}
}
}
}
}
The expected result is that the first text file shows the numbers as they were when they were randomly created, while the second text file shows them after they are sorted. As of current, I can get the first file to show the numbers in a random order, but cannot even get the second text file to be created, let alone the numbers sorted and wrote on it.
Arrays.sort returns void (see doc).
What you could do is sort the array.
Arrays.sort(numbers);
And after write the result to a file.
for (int i = 0; i < 100; i ++) {
output.print(numbers[i] + " ");
}
Complete Example:
import java.io.File;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Scanner;
public class Numbers {
public static void main(String[] args) throws Exception {
//check if source file exists
File number = new File("Numbers.txt");
File sorted = new File("Sorted.txt");
if (!number.exists()) {
try ( // create the file
PrintWriter output = new PrintWriter(number);
) {
for (int i = 0; i <= 100; i++) {
output.print(((int)(Math.random() * 999) + 1) + " ");
}
}
}
try (
Scanner input = new Scanner(number);
) {
int[] numbers = new int[100];
for (int i = 0; i < 100; i++) {
numbers[i] = input.nextInt();
}
if (!sorted.exists()) {
try (
PrintWriter output = new PrintWriter(sorted)
) {
Arrays.sort(numbers);
for (int i = 0; i < 100; i ++) {
output.print(numbers[i] + " ");
}
}
}
}
} }
I would suggest extracting to a method the code that writes to the file. Since it would only need a path and content it can be reused for both files and it will make your life way easier.
It is also very helpful if you include the line number where you get the error since it's not always clear where the exception is thrown.
From what I understood from your question the problem is about generating some numbers, write them to a file and lastly sort them and write them to another file. I wrote some code using the same approach but a bit more restructured. I hope it helps.
public static void main(String[] args) {
int[] randomData = new Random().ints(100).toArray();//just a short way to generate numbers. Use your own.
File numbers = writteArray("Numbers.txt", randomData);
Arrays.sort(randomData);
File sorted = writteArray("Sorted.txt", randomData);
}
public static File writteArray(String Path, int[] randomNumbers){
File numbers = new File(Path);
//if the file does not exist it will be created automatically
try(PrintWriter fileWritter = new PrintWriter(numbers)) {
//just an example of how to write them. Use your prefered format
//also you can use the append function to not lose the previous content
for (int e : randomNumbers)
fileWritter.printf(" %d", e);
fileWritter.println();
}
catch (FileNotFoundException e){
e.printStackTrace();
}
return numbers;
}
As an edit you can make the writeArray() function return void if you don't need the files after.

Reading text File and putting it in a array

I am trying to take a set of 25 numbers from a text file and convert it into a array. But I am lost.
I have read some other questions similar to this, but all of them used imports and extras, and I don't want to use any imports besides import java.io.*; nor any list.
Also the for loop within this is method is me just messing with it, because I couldn't figure it out.
public static int[] processFile (String filename) throws IOException, FileNotFoundException {
BufferedReader inputReader = new BufferedReader (new InputStreamReader(new FileInputStream(filename)));
String line;
int[] a = new int[25];
while (( line = inputReader.readLine()) != null){
int intValue = Integer.parseInt(line); //converts string into int
for (int i = 0; i < a.length; i++){
a[intValue]++;
}
}
return a;
}
public static void printArray (int[] a) {
for (int i = 0; i<a.length; i++) {
System.out.println (a[i]);
}
}
public static void main(String[] args) throws IOException, FileNotFoundException {
int [] array = processFile("C:\Users\griff_000\Desktop\TestWeek13.txt");
printArray(array);
}
I'm unclear about your whole import restriction, why exactly are you trying to limit the number of imports you have?
Anyway, looking at your code, it seems like the concept of arrays isn't all that clear with you.
Arrays are accessed under the syntax:
array[index] = value;
looking at your code, the line a[intValue]++; is actually finding the array index intValue (the number read from file) and incrementing it by one. Not only is this not what you want, numbers over the array length will cause an ArrayIndexOutOfBoundsException.
Making said amendments we get:
public static int[] processFile (String filename) throws IOException, FileNotFoundException{
BufferedReader inputReader = new BufferedReader (new InputStreamReader(new FileInputStream(filename)));
String line;
int[] a = new int[25];
int i = 0; // We need to maintain our own iterator when using a while loop
while((line = inputReader.readLine()) != null){
int intValue = Integer.parseInt(line); //converts string into int
a[i] = intValue; // Store intValue into the array at index i
i++; // Increment i
}
return a;
}
note the additional variable i being used in this context to facilitate the incrementing index number being used to access the array. If you examine this method carefully, a input file longer than 25 elements would also throw ArrayIndexOutOfBoundsException due to the variable i becoming 25 (beyond the limits of the array). To fix, I'd suggest changing the loop structure to a for-loop (assuming your input array is of fixed size) as follows:
public static int[] processFile (String filename) throws IOException, FileNotFoundException{
BufferedReader inputReader = new BufferedReader (new InputStreamReader(new FileInputStream(filename)));
String line;
int[] a = new int[25];
for(int i = 0; i < a.length; i++){
String line = inputReader.readLine(); // Move the readline code inside the loop
if(line == null){
// We hit EOF before we read 25 numbers, deal appropriately
}else{
a[i] = Integer.parseInt(line);
}
}
return a;
}
Note how the for loop integrates the iterator variable into one nice elegant line, keeping the rest of the code neat and readable.
Your mistake is in the line a[intValue]++;. You are telling Java to find the element at [intValue] and add 1 to it's current value. From your question, I understood that you want to put intValue as the array element.
Since you are using i as the iterator, to add the element simply use:
a[i] = intValue;
What you are doing here:
a[intValue]++;
is increasing the array position of the read value by one. If the number read is 2000 you are increasing a[2000]
you might want to do this
a[i]=intValue;

Simple issue about possible to re use java Scanner?

I am still new to java and is it possible to re use the Scanner object?
The below example is I am reading a file to do characters, words and lines count. I know there must be a better way to do counting with one scanner object only but that is not the main point. I just wonder why there is input.close() but no input.open() or input.reset etc.. Since I am actually reading the same file, is it possible to create only one Scanner object and pass for 3 methods to use? Thanks
public class Test {
/**
* #throws java.io.FileNotFoundException
*/
public static void main(String[] args) throws FileNotFoundException {
File file = new File("demo.java");
Scanner input = new Scanner(file);
Scanner input2 = new Scanner(file);
Scanner input3 = new Scanner(file);
int lines = 0;
int words = 0;
int characters = 0;
checkCharacters(input3);
checkLines(input);
checkwords(input2);
}
private static void checkLines(Scanner input) {
int count = 0;
while (input.hasNext()) {
String temp = input.nextLine();
String result = temp;
count++;
}
System.out.printf("%d lines \n", count);
}
private static void checkwords(Scanner input2) {
int count = 0;
while (input2.hasNext()) {
String temp = input2.next();
String result = temp;
count++;
}
System.out.printf("%d words \n", count);
}
private static void checkCharacters(Scanner input3) {
int count = 0;
while (input3.hasNext()) {
String temp = input3.nextLine();
String result = temp;
count += temp.length();
}
System.out.printf("%d characters \n", count);
}
}
No, there's no way to reset the Scanner from a method on the Scanner. You might be able to do it if you passed in an InputStream into the scanner and then reset the stream directly but I don't think it's worth it.
You seem to be parsing the same file 3 times and processing the same input 3 times. That seems like a waste of processing. Couldn't you perform all 3 counts at once?
private static int[] getCounts(Scanner input) {
int[] counts = new int[3];
while(input.hasNextLine()){
String line = input.nextLine();
counts[0]++; // lines
counts[2]+=line.length(); //chars
//count words
//for simplicity make a new scanner could probably be better
//using regex or StringTokenizer
try(Scanner wordScanner = new Scanner(line)){
while (wordScanner.hasNext()) {
wordScanner.next();
count[1] ++; //words
}
}
}
return counts;
}
Of course the Object Oriented way would be to return a new object named something like Counts with methods to getNumLines(), getNumChars() etc.
EDIT
One thing to note, I kept the calculations the same as you had in the original question. I'm not sure if the counts will always be accurate especially characters since Scanner may not return all end of line characters so the chars count may be off and the number of lines may be off if there are consecutive blank lines? You would need to test this.
No it is not possible because as the documentation says
void close()
throws IOException
Closes this stream and releases any system resources associated with
it. If the stream is already closed then invoking this method has no
effect.
Once a resource is relaesed there is no way to get it back, untill you have a reference to it , which is actually closed

Using BufferedReader in java to read a line of ints before reading lines of Strings from a text file

I have a text file that looks like this:
5 10
ahijkrewed
llpuvesoru
irtxmnpcsd
kuivoqrsab
eneertlqzr
tree
alike
cow
dud
able
dew
The first number on the first line, 5, is the number of rows for a word-search puzzle, and 10 is the number of columns for the puzzle. The next five lines is the puzzle. I need to know how to place 5 into a rows integer, and 10 to a columns integer. Then I need to skip to the next line to read the strings. Using a modified file with only the 5 lines for the puzzle I figured out how to place the puzzle portion into a 2d array, but I need a way to set the size of that array from the first line of the proper text fle.
I wrote this:
import java.io.*;
class SearchDriver {
public static void processFile(String filename) throws FileNotFoundException, IOException {
FileReader fileReader = new FileReader(filename);
BufferedReader in = new BufferedReader(fileReader);
// declare size of array needed
//
// int rows and columns need to be read in from first
// line of the file which will look like: X Y
//
// so i need rows = X and columns = Y
int rows = 5;
int columns = 10;
String[][] s = new String[rows][columns];
// start to loop through the file
//
// this will need to start at the second line of the file
for(int i = 0; i < rows; i++) {
s[i] = in.readLine().split("(?!^)");
}
// print out the 2d array to make sure i know what i'm doing
for(int i=0;i<rows;i++) {
for(int j=0;j<columns;j++) {
System.out.println("(i,j) " + "(" + i + "," + j + ")");
System.out.println(s[i][j]);
}
}
}
public static void main(String[] args)
throws FileNotFoundException, IOException {
processFile("puzzle.txt");
}
}
Any help would be appreciated including any websites with examples and extensive documentation on reading in files using BufferedReader.
This seems like homework, so I won't give you the whole solution, but here's a hint to get you started:
String firstLine = in.readLine();
//You now have the two integers in firstLine, and you know that they're
//separated by a space. How can you extract them into int rows and int columns?
String[][] s = new String[rows][columns];
I'd suggest a simpler solution: Use java.util.Scanner instead. There are lots of examples of use online (and in the link I provided), but this might get you started:
Scanner sc = new Scanner(new File(filename));
int rows = sc.nextInt();
int cols = sc.nextInt();
sc.nextLine(); // move past the newline
for(int i = 0; i < rows; i++) {
String line = sc.nextLine();
// etc...
}

Categories

Resources