Reputation: 17
I am currently trying to count how many words from a textfile have even numbers and odd numbers of characters but I cant seem to get it to work. so far i have done
int countEven = 0;
int countOdd = 0;
for (int i = 0; i <latinLength.length(); i++) {
if (Character.isLetter(latinLength.charAt(i))) {
countEven++;
} else {
countOdd++;
}
}
System.out.println("Total number of unique even words in Latin names = " + countEven);
System.out.println("Total number of unique odd words in Latin names = " + countOdd);
}
i think what i did wrong is i am not accessing the right part of the text file. i do have a get function for the information i want which is getLatinName, but i am not sure how to implement it correctly
String tempLatinName = " ";
String latinLength = " ";
int letters = 0;
for (int i = 0; i < info.size(); i++) {
tempLatinName = info.get(i).getLatinName();
latinLength = tempLatinName.replace(" ","");
letters += latinLength.length();
}
System.out.println("Total number of letters in all Latin names = " + letters);
i have edited the code to show the bit i have done before trying to calculate how many words have odd and even number of characters, the code above is to calculate the total number of characters in each word and then gives me a total
/**
*
* @author g_ama
*/
import java.io.*;
import java.util.*;
public class Task1 {
/**
* @param args the command line arguments
*/
public static void main(String[] args) throws FileNotFoundException, IOException {
BufferedReader reader = new BufferedReader(new FileReader("shark-data.txt"));
String line;
List<Shark> info = new ArrayList<>();
while ((line = reader.readLine()) != null) {
String[] data = line.split(":");
int MaxLength = Integer.parseInt(data[2]);
int MaxDepth = Integer.parseInt(data[3]);
int MaxYoung;
try {
MaxYoung = Integer.parseInt(data[4]);
} catch (Exception X) {
MaxYoung = -1;
}
int GlobalPresence = Integer.parseInt(data[5]);
ArrayList<String> OceanicRegion = new ArrayList<>();
String[] Region = data[6].split(",");
for (String Element : Region) {
OceanicRegion.add(Element);
}
Shark shark = new Shark(data[0], data[1], MaxLength, MaxDepth, MaxYoung, GlobalPresence, OceanicRegion);
info.add(shark);
}
Collections.sort(info);
System.out.println("The three largest sharks");
System.out.println(info.get(info.size() - 1).getCommonName() + ", " + info.get(info.size() - 1).MaxLength + " cm");
System.out.println(info.get(info.size() - 2).getCommonName() + ", " + info.get(info.size() - 2).MaxLength + " cm");
System.out.println(info.get(info.size() - 3).getCommonName() + ", " + info.get(info.size() - 3).MaxLength + " cm");
System.out.println("The three smallest sharks");
System.out.println(info.get(0).getCommonName() + ", " + info.get(0).MaxLength + " cm");
System.out.println(info.get(1).getCommonName() + ", " + info.get(1).MaxLength + " cm");
System.out.println(info.get(2).getCommonName() + ", " + info.get(2).MaxLength + " cm");
//count total characters for Latin Name
String tempLatinName = " ";
String latinLength = " ";
int letters = 0;
for (int i = 0; i < info.size(); i++) {
tempLatinName = info.get(i).getLatinName();
latinLength = tempLatinName.replace(" ", "");
letters += latinLength.length();
}
System.out.println("Total number of letters in all Latin names = " + letters);
//count even or odd words
int countEven = 0;
int countOdd = 0;
for (int i = 0; i < latinLength.length(); i++) {
if (Character.isLetter(latinLength.charAt(i))) {
countEven++;
} else {
countOdd++;
}
}
System.out.println("Total number of unique even words in Latin names = " + countEven);
System.out.println("Total number of unique odd words in Latin names = " + countOdd);
}
}
Upvotes: 1
Views: 6915
Reputation: 25903
Currently you are only counting how many letters and non-letters your text has. That is of course not the amount of even words or odd words.
For example if you have a word like
test12foo!$bar
Your code will currently output
countEven => 10 // Amount of letters (testfoobar)
countOdd => 4 // Amount of non-letters (12!$)
Compare this to your if-condition:
if (Character.isLetter(latinLength.charAt(i))) {
countEven++;
} else {
countOdd++;
}
What you want is to count how often the length of your words is even or odd, so suppose words like
test // length 4, even
foo // length 3, odd
bartest // length 7, odd
then you want
countEven => 1 // (test)
countOdd => 2 // (foo, bartest)
Instead you will need to split your text into words (tokenize). After that you will need to count, for each word, the amount of characters. If that is even you may increase countEven
by one. Likewise countOdd++
if it's an odd number.
The core will be this condition
word.length() % 2 == 0
it is true
if the word has an even length and false if it's odd. You can easily verify this yourself (%
returns the remainder after division, 0
or 1
in this case).
Let's assume your text structure is simple and words are always separated by whitespace
, i.e. something like
test foo bar John Doe
All in all your code could then look like
Path path = Paths.get("myFile.txt");
AtomicInteger countEven = new AtomicInteger(0);
AtomicInteger countOdd = new AtomicInteger(0);
Pattern wordPattern = Pattern.compile(" ");
Files.lines(path) // Stream<String> lines
.flatMap(wordPattern::splitAsStream) // Stream<String> words
.mapToInt(String::length) // IntStream length
.forEach(length -> {
if (length % 2 == 0) {
countEven.getAndIncrement();
} else {
countOdd.getAndIncrement();
}
});
System.out.println("Even words: " + countEven.get());
System.out.println("Odd words: " + countOdd.get());
Or without all that Stream
stuff:
Path path = Paths.get("myFile.txt");
List<String> lines = Files.readAllLines(path);
List<String> words = new ArrayList<>();
// Read words
for (String line : lines) {
String[] wordsOfLine = line.split(" ");
words.addAll(Arrays.asList(wordsOfLine));
}
// Count even and odd words
int countEven = 0;
int countOdd = 0;
for (String word : words) {
if (word.length() % 2 == 0) {
countEven++;
} else {
countOdd++;
}
}
System.out.println("Even words: " + countEven);
System.out.println("Odd words: " + countOdd);
As you've just added your specific code I'll add a solution adapted to it.
In your code the list info
contains all Shark
s. From those sharks the words you want to consider is represented by Shark#getLatinName
. So all you will need to do is some kind of this:
List<String> words = info.stream() // Stream<Shark> sharks
.map(Shark::getLatinName) // Stream<String> names
.collect(Collectors.toList());
and you can use this words
exactly as shown in the other code examples. Alternatively you don't need to collect everything into a new list, you can directly stay in the Stream
and continue with the stream-approach shown before. All in all:
AtomicInteger countEven = new AtomicInteger(0);
AtomicInteger countOdd = new AtomicInteger(0);
info.stream() // Stream<Shark> sharks
.map(Shark::getLatinName) // Stream<String> names
.mapToInt(String::length) // IntStream length of names
.forEach(length -> {
if (length % 2 == 0) {
countEven.getAndIncrement();
} else {
countOdd.getAndIncrement();
}
});
System.out.println("Even words: " + countEven);
System.out.println("Odd words: " + countOdd);
And substitute this into that part in your code:
//count even or odd words
(substitute here)
Upvotes: 3