I'm trying to simplify this Java code by adding arrays, but I'm having difficulty.
The code that I have so far that works:
import java.io.FileReader;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Homework4A {
public static void main(String[] args) throws FileNotFoundException {
Scanner scan = new Scanner(System.in);
System.out.print("Enter name of the input file: ");
String fileName = scan.next();
try (Scanner inFile = new Scanner(new FileReader(fileName))) {
char number0 = '0';
char number1 = '1';
char number2 = '2';
char number3 = '3';
char number4 = '4';
char number5 = '5';
char number6 = '6';
char number7 = '7';
char number8 = '8';
char number9 = '9';
int count0 = 0;
int count1 = 0;
int count2 = 0;
int count3 = 0;
int count4 = 0;
int count5 = 0;
int count6 = 0;
int count7 = 0;
int count8 = 0;
int count9 = 0;
while (inFile.hasNextLine()) {
String line = inFile.nextLine();
for (int i = 0; i < line.length(); i ) {
if (line.charAt(i) == number0) {
count0 ;
}
else if (line.charAt(i) == number1) {
count1 ;
}
else if (line.charAt(i) == number2) {
count2 ;
}
else if (line.charAt(i) == number3) {
count3 ;
}
else if (line.charAt(i) == number4) {
count4 ;
}
else if (line.charAt(i) == number5) {
count5 ;
}
else if (line.charAt(i) == number6) {
count6 ;
}
else if (line.charAt(i) == number7) {
count7 ;
}
else if (line.charAt(i) == number8) {
count8 ;
}
else if (line.charAt(i) == number9) {
count9 ;
}
}
}
System.out.println("\n-= Count of Thistles in =-");
System.out.println("-= the Hundred Acre Wood =-\n");
System.out.println(" -----------");
System.out.println(" type count");
System.out.println(" -----------");
System.out.println(" 0 " count0);
System.out.println(" 1 " count1);
System.out.println(" 2 " count2);
System.out.println(" 3 " count3);
System.out.println(" 4 " count4);
System.out.println(" 5 " count5);
System.out.println(" 6 " count6);
System.out.println(" 7 " count7);
System.out.println(" 8 " count8);
System.out.println(" 9 " count9);
System.out.println(" -----------");
}
}
}
However, it's kind of a brute-force attack. The spot of difficulty I'm running into is figuring out where to create and pass arrays. Since the code has to read the external file, should the arrays be created and passed in the while statement?
For further reference, the text file that is being read looks like this:
The goal is to count the occurrences of digits only.
CodePudding user response:
As you stated, you could use arrays.
I would suggest 2 arrays
- One to hold the digits to catch
- Second one for the counts
Initialization of the arrays
char[] numbers = new char[10];
//initialize of numbers(char) to count
for(int i = 0; i < numbers.length; i ) {
numbers[i] = (char) ('0' i);
}
int[] counts = new int[10]; //no initialization needed because int is default 0
In the for
-loop where you iterate over the line, add a nested for loop, that iterates over the numbers
-array. Here is the whole while
loop:
while (inFile.hasNextLine()) {
String line = inFile.nextLine();
for (int i = 0; i < line.length(); i ) {
for(int j = 0; j < numbers.length; j ) {
if(line.charAt(i) == numbers[j]) {
counts[j] ;
}
}
}
}
For the output just use another for over the arrays:
for(int i = 0; i < numbers.length; i ) {
System.out.println(" " numbers[i] " " counts[i]);
}
Edit: Another solution using a Map
//...
Map<Character, Integer> charCounts = new HashMap<>();
for (int i = 0; i < 10; i ) {
charCounts.put((char) ('0' i), 0);
}
while (inFile.hasNextLine()) {
String line = inFile.nextLine();
for (int i = 0; i < line.length(); i ) {
charCounts.computeIfPresent(line.charAt(i), (key, val) -> val 1);
}
}
//...
for (Character number : charCounts.keySet()) {
System.out.println(" " number " " charCounts.get(number));
}
With this solution you can easily extend your program to count any occuring character. Just remove the initialization of the map and add this line below the computeIfPresent
.
charCounts.putIfAbsent(line.charAt(i), 1);
CodePudding user response:
Yes. I would say it can be simplified a great deal with an array. You don't need seperate sentinels for the values, you can check they are in range and then use Character.digit
to parse them. Something like,
Scanner scan = new Scanner(System.in);
System.out.print("Enter name of the input file: ");
String fileName = scan.next();
try (Scanner inFile = new Scanner(new FileReader(fileName))) {
int[] count = new int[10];
while (inFile.hasNextLine()) {
String line = inFile.nextLine();
for (int i = 0; i < line.length(); i ) {
if (line.charAt(i) >= '0' && line.charAt(i) <= '9') {
count[Character.digit(line.charAt(i), 10)] ;
}
}
}
System.out.println("\n-= Count of Thistles in =-");
System.out.println("-= the Hundred Acre Wood =-\n");
System.out.println(" -----------");
System.out.println(" type count");
System.out.println(" -----------");
for (int i = 0; i < count.length; i ) {
System.out.printf(" %d %d%n", i, count[i]);
}
System.out.println(" -----------");
}
CodePudding user response:
With Java 8 you can use Files.lines
to get a Stream
of all the lines in a file.
Then you can transform the stream to a stream over every char
using flatMap
and in the end collect it to a map that has the Character
as key and the count of the character as value.
try (Stream<String> stream = Files.lines(Paths.get(fileName)) {
Map<Character, Long> charCountMap = stream
.flatMap(line -> line.chars().mapToObj(c -> (char) c))
.collect(Collectors.groupingBy(c -> c, Collectors.counting()));
System.out.println(" 0 " charCountMap.getOrDefault('0', 0));
} catch (IOException e) {
e.printStackTrace();
}
Probably the way I would do it in a real world scenario, because it's short, but just for practice the other answers are better.
CodePudding user response:
You can use a single array for this and index notation. Each array index should hold the quantity of digits. Much more clear.
import java.io.FileReader;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Homework4A {
public static void main(String[] args) throws FileNotFoundException {
Scanner scan = new Scanner(System.in);
System.out.print("Enter name of the input file: ");
String fileName = scan.next();
try (Scanner inFile = new Scanner(new FileReader(fileName))) {
int[] count = new int[10];
while (inFile.hasNextLine()) {
String line = inFile.nextLine();
for (int i = 0; i < line.length(); i ) {
try {
int c = Character.getNumericValue(line.charAt(i));
count[c] = 1;
} catch (Exception e) { }
}
}
System.out.println("\n-= Count of Thistles in =-");
System.out.println("-= the Hundred Acre Wood =-\n");
System.out.println(" -----------");
System.out.println(" type count");
System.out.println(" -----------");
for (int i = 0; i < 10; i )
System.out.println(" " i " " count[i]);
System.out.println(" -----------");
}
}
}