gamal
gamal

Reputation: 17

Counting even and odd number of letters in words

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

Answers (1)

Zabuzard
Zabuzard

Reputation: 25903

Explanation

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)

Solution

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);

Adjusted to your specific code

As you've just added your specific code I'll add a solution adapted to it.

In your code the list info contains all Sharks. 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

Related Questions