Counting even and odd number of letters in words - java

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

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)

Related

Is there a way to println to enumerate and list words in a string?

I'm trying to write a java program that will count the number of words in a declared sentence and then break the sentence up into words in order to list the words with numerical values and also display the words. I have the total count solved, but I can't seem to break up the words in the sentence and then list them chronologically. I can do it with characters, but not words.
I have explored both the Java Cookbook and other places to find a solution but I just do not understand it well enough. As I said, I can get the characters to count, and I can tally the words, but I can't get the individual words to print on separate lines with numerical values for their count in the string.
public class MySentenceCounter {
public static void main(String[] args) {
String sentence = "This is my sentence and it is not great";
String[] wordArray = sentence.trim().split("\\s+");
int wordCount = wordArray.length;
for (int i=0; i < sentence.length( ); i++)
System.out.println("Char " + i + " is " + sentence.charAt(i));
//this produces the character count but I need it to form words, not individual characters.
System.out.println("Total is " + wordCount + " words.");
}
}
Expected results should look like:
1 This
2 is
3 my
4 sentence
5 and
6 it
7 is
8 not
9 great
Total is 9 words.
Iterate over the wordArray variable you created rather than the original sentence string in your for loop:
public class MySentenceCounter {
public static void main(String[] args) {
String sentence = "This is my sentence and it is not great";
String[] wordArray = sentence.trim().split("\\s+");
// String[] wordArray = sentence.split(" "); This would work fine for your example sentence
int wordCount = wordArray.length;
for (int i = 0; i < wordCount; i++) {
int wordNumber = i + 1;
System.out.println(wordNumber + " " + wordArray[i]);
}
System.out.println("Total is " + wordCount + " words.");
}
}
Output:
1 This
2 is
3 my
4 sentence
5 and
6 it
7 is
8 not
9 great
Total is 9 words.
A bit more elegant solution using IntStream instead of a for-loop:
import java.util.stream.IntStream;
public class ExampleSolution
{
public static void main(String[] args)
{
String sentence = "This is my sentence and it is not great";
String[] splitted = sentence.split("\\s+");
IntStream.range(0, splitted.length)
.mapToObj(i -> (i + 1) + " " + splitted[i])
.forEach(System.out::println);
System.out.println("Total is " + splitted.length + " words.");
}
}
Try avoiding too much complexity, the following does it just fine
public class MySentenceCounter {
public static void main(String[] args) {
String sentence = "This is my sentence and it is not great";
int ctr = 0;
for (String str : sentence.trim().split("\\s+")) {
System.out.println(++ctr + "" + str) ;
}
System.out.println("Total is " + ctr + " words.");
}
}

Creating a program in java that counts sentences, paragraphs, letters and words

I need to create a program that counts the frequency of characters in a text file, as well as the number of paragraphs words and sentences.
I have a problem where when my program outputs the frequency of the letters the program outputs multiple outputs for each letter in the alphabet.
Output should be like this:
if input was "hello world!"
(should output this for all letters of the alphabet):
The letter a has been found 0 times
the letter b has been found 0 times
(until it reaches the letters that appear and then shows how many times they appear)
number of paragraphs: 1
number of sentences: 1
number of characters:10
number of words: 2
I have been working on this for weeks now and still can't find a solution.
package SuperCounter2;
import java.io.*;
public class SuperCounter2 {
public static void main(String[] args) throws IOException {
File file = new File("//Users//4617621//Desktop//This is the most stupid assignment");
FileInputStream fileStream = new FileInputStream(file);
InputStreamReader input = new InputStreamReader(fileStream);
BufferedReader reader = new BufferedReader(input);
String line;
int countWord = 0;
int sentenceCount = 0;
int characterCount = 0;
int paragraphCount = 1;
int whitespaceCount = 0;
while ((line = reader.readLine()) != null) {
int ci, i, j, k, l = 0;
char c, ch;
i = line.length();
if (line.equals("")) {
paragraphCount++;
}
if (!(line.equals(""))) {
characterCount += line.length();
String[] wordList = line.split("\\s+");
countWord += wordList.length;
whitespaceCount += countWord - 1;
String[] sentenceList = line.split("[!?.:]+");
sentenceCount += sentenceList.length;
}
int counter = 0;
for (int m = 0; m < line.length(); m++) {
counter++;
}
for (c = 'A'; c <= 'z'; c++) {
k = 0;
for (j = 0; j < i; j++) {
ch = line.charAt(j);
if(ch == c) {
k++;
System.out.println(" the character " + c + " has occured " + k + " times");
}
}
}
}
System.out.println("Total word count = " + countWord);
System.out.println("Total number of sentences = " + sentenceCount);
System.out.println("Total number of characters = " + characterCount);
System.out.println("Number of paragraphs = " + paragraphCount);
System.out.println("Total number of whitespaces = " + whitespaceCount);
}
}
I think that you could see this as simply counting the number of periods, spaces, carriage returns, etc.
It might be easier to do this by taking it a letter at a time instead of a word at a time.
The only place it would get tricky (where you need to look at more than one thing at a time) is cases where there might be "word1.word2", "word1. word2" or "word1. word2" (two spaces). For those you might have to keep a flag that said if the previous character was a "word separator"(Period, space, c/r) then don't count another word.
Otherwise it seems pretty straight forward. Look at the character, if it is a period add it to the line count&word count, if it's a space add it to the word count, if it's a c/r add it to the paragraph, and word counts, and then track each letter (probably in a Map)
The inside of the loop should be about 5 lines of code if you count the flag manipulation.
Not writing code because this sounds like homework.
PS: It actually seems like a pretty cool assignment :)

Java Scanner class to JOptionPane class?

This is what this code does: Allows the user to enter one character (L or S) and three integers between 100 and 1000. The program outputs the following:
Display the message: “Wrong input!” if the numbers are not included in the interval [100-1000] using method CheckInput;
The largest number if the user enters the letter L, using method Largest;
The smallest number if the user enters the letter S, using method Smallest;
All numbers and their digits reversed using the method Backwards;
Using the method EvenOrOdd that takes one integer and outputs ‘True’ if the number is even or ‘False’ if it is odd, output the numbers entered followed by ‘True’ or ‘False’
Use the method CheckDivisor, that takes all three numbers and checks if the first number is a divisor of the second or third, and returns ‘True’ or ‘False’
Make the output easier to understand and add two more methods to the program
For number 7 I added, double and sum
import java.util.Arrays;
import java.util.Scanner;
public class Words {
public static void main(String[] args) {
Scanner scan = new Scanner(System. in );
while (scan.hasNext()) {
String line = scan.nextLine();
if (line.equals("exit")) {
break;
}
String[] words = line.split(" ");
//alphabetical
System.out.print("Alphabetical order: ");
alphabetical(words);
// concatenate and mix
String[] sorted = words.clone();
Arrays.sort(sorted);
String all = "";
for (String s: sorted) {
all += s;
}
System.out.println("All together: " + all);
System.out.println("Concatenate and Mix: " + mix(all));
// find first 2 and last 2 letters
first2last2(all);
//middlexx
System.out.println("Replace middle with xx or yy: " + middlexx(all));
System.out.println();
}
}
private static void alphabetical(String[] words) {
String[] ws = words.clone();
Arrays.sort(ws);
for (int i = 0; i < ws.length; i++) {
if (i != 0) {
System.out.print(" ");
}
System.out.print(ws[i]);
}
System.out.println();
}
private static String mix(String s) {
return s.replaceAll("a|e|i|o|u", "x");
}
private static void first2last2(String s) {
if (s.length() < 5) {
System.out.println("Invalid command!");
} else {
System.out.println("First two characters: " + s.substring(0, 2));
System.out.println("Last two characters: " + s.substring(s.length() - 2, s.length()));
}
}
private static String middlexx(String s) {
if (s.length() % 2 == 0) {
return s.substring(0, s.length() / 2) + "xx" + s.substring(s.length() / 2, s.length());
} else {
return s.substring(0, s.length() / 2) + "yy" + s.substring(s.length() / 2 + 1, s.length());
}
}
}
How would I convert this into JOptionPane class? I want the program to ask the user to type L or S, and to type 3 integers using something like this:
String input1 = JOptionPane.showInputDialog("Please enter L or S");
a = Double.valueOf(input1).doubleValue();
You can take input from JOptionPane like this
JOptionPane.showInputDialog ( "put your message here" );
Sample Code
Object[] possibilities = {"ham", "spam", "yam"};
String s = (String)JOptionPane.showInputDialog(
frame,
"Complete the sentence:\n"
+ "\"Green eggs and...\"",
"Customized Dialog",
JOptionPane.PLAIN_MESSAGE,
icon,
possibilities,
"ham");
//If a string was returned, say so.
if ((s != null) && (s.length() > 0)) {
setLabel("Green eggs and... " + s + "!");
return;
}
//If you're here, the return value was null/empty.
setLabel("Come on, finish the sentence!");
For More: https://docs.oracle.com/javase/tutorial/uiswing/components/dialog.html

Word count from text

This is my code to work out the length of a word:
public class WordCount {
public static void main (String args []) {
String text;
text = "Java";
System.out.println (text);
//Work out the length
String [] input = text.split(" ");
int MaxWordLength = 0;
int WordLength = 0;
for (int i = 0; i < input.length; i++)
{
MaxWordLength = input[i].length();
WordLength = MaxWordLength;
} //End of working out length
//Work out no. of words
int[] intWordCount = new int[WordLength + 1];
for(int i = 0; i < input.length; i++) {
intWordCount[input[i].length()]++; }
for (int i = 1; i < intWordCount.length; i++) {
System.out.println("There are " + intWordCount[i] + " words of length " + MaxWordLength);
}
}
}
The problem I am having is that when it prints out the length of the word, I get these results:
Java
There are 0 words of length 4
There are 0 words of length 4
There are 0 words of length 4
There are 1 words of length 4
But when I change the text to "J" this prints out:
J
There are 1 words of length 1
Any idea why it's doing that?
P.S. I'm kind of new to Java and any help would be appreciated.
I am not sure if you want to count letter or word because your code counts letter to me.
Just you need to change this line from
String [] input = text.split(" ");
to
String [] input = text.split("");
and your program works perfectly.
input: Java
output: There are 4 letters of length 1 <- Hope this is the expected result for you
Source: Splitting words into letters in Java
You can achieve this in better and less headache by using Lambda in Java
Code:
import java.util.*;
public class LambdaTest
{
public static void main (String[] args)
{
String[] st = "Hello".split("");
Collection myList = Arrays.asList(st);
System.out.println("your word has " + myList.stream().count() + "letters");
}
}
Output:
your word has 5 letters CLEARLY in length 1
My answer when you cleared what your issue is
Code:
public class WordCount
{
public static void main (String[] args)
{
String text ="";
int wordLenght = 0;
text = "Java is awesome for Me";
System.out.println (text);
String [] input = text.split(" ");
List<Integer> list = new ArrayList<>();
for (int i = 0; i < input.length; i++)
{
list.add(input[i].length());
}
Set<Integer> unique = new HashSet<Integer>(list);
for (Integer length : unique) {
System.out.println("There are " + Collections.frequency(list, length) + " words of length " + length);
}
}
}
output:
There are 2 words of length 2
There are 1 words of length 3
There are 1 words of length 4
There are 1 words of length 7
Note: Read about HashSet and Set in Java
Source: http://javarevisited.blogspot.com/2012/06/hashset-in-java-10-examples-programs.html
Let's walk through this:
public class WordCount {
public static void main (String args []) {
String text;
text = "Java";
text is equal to "Java".
System.out.println (text);
Prints "Java"
//Work out the length
String [] input = text.split(" ");
This splits the string "Java" on spaces, of which there are none. So input (which I'd recommend be renamed to something more indicative, like inputs) is equal to an array of one element, and that one element is equal to "Java".
int MaxWordLength = 0;
int WordLength = 0;
for (int i = 0; i < input.length; i++)
{
MaxWordLength = input[i].length();
For each element, of which there is only one, MaxWordLength is set to the length of the first (and only) element, which is "Java"...whose length is 4.
WordLength = MaxWordLength;
So WordLength is now equal to 4.
} //End of working out length
//Work out no. of words
int[] intWordCount = new int[WordLength + 1];
This creates an int array of [WordLength + 1] elements (which is equal to [4 + 1], or 5), where each is initialized to zero.
for(int i = 0; i < input.length; i++) {
intWordCount[input[i].length()]++; }
For each element in input, of which there is only one, this sets the input[i].length()-th element--the fifth, since input[i] is "Java" and it's length is four--to itself, plus one (because of the ++).
Therefore, after this for loop, the array is now equal to [0, 0, 0, 0, 1].
for (int i = 1; i < intWordCount.length; i++) {
System.out.println("There are " + intWordCount[i] + " words of length " + MaxWordLength);
So this naturally prints the undesired output.
}
}
}
Your output is different when the input is only "J", because the intWordCount array is shortened to input[i].length() elements, which is now 1. But the value of the last element is still set to "itself plus one", and "itself" is initialized to zero (as all int-array elements are), and then incremented by one (with ++).
for (int i = 1; i < intWordCount.length; i++) {
System.out.println("There are " + intWordCount[i] + " words of length " + MaxWordLength);
}
1) You print out words with intWordCount[i] == 0, which is why you have the "There are 0 words of length X"
2) System.out.println("There are " ... + MaxWordLength); should probably be System.out.println("There are " ... + i);, so you have "There are 0 words of length 1" , "There are 0 words of length 2", etc
I know this question has been solved long time ago, but here is another solution using new features of Java 8. Using Java streams the whole exercise can be written in one line:
Arrays.asList(new String[]{"Java my love"}) //start with a list containing 1 string item
.stream() //start the stream
.flatMap(x -> Stream.of(x.split(" "))) //split the string into words
.map((String x) -> x.length()) //compute the length of each word
.sorted((Integer x, Integer y) -> x-y) //sort words length (not necessary)
.collect(Collectors.groupingBy(x -> x, Collectors.counting())) //this is tricky: collect results to a map: word length -> count
.forEach((x,y) -> {System.out.println("There are " + y + " word(s) with " + x + " letter(s)");}); //now print each result
Probably in few year time this would be a preferred method for solving such problems. Anyway it is worth knowing that such alternative exists.
To count words in text with we used Pattern class with while loop:
I. Case Sensitive word counts
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class CountWordsInText {
public static void main(String[] args) {
String paragraph = "I am at office right now."
+ "I love to work at office."
+ "My Office located at center of kathmandu valley";
String searchWord = "office";
Pattern pattern = Pattern.compile(searchWord);
Matcher matcher = pattern.matcher(paragraph);
int count = 0;
while (matcher.find()) {
count++;
}
System.out.println(count);
}
}
II. Case Insensitive word counts
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class CountWordsInTextCaseInsensitive {
public static void main(String[] args) {
String paragraph = "I am at office right now."
+ "I love to work at oFFicE."
+"My OFFICE located at center of kathmandu valley";
String searchWord = "office";
Pattern pattern = Pattern.compile(searchWord, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(paragraph);
int count = 0;
while (matcher.find())
count++;
System.out.println(count);
}
}
Idk, but using the length method as much as you have to figure out how the length mechanism works is like defining a word using the word. It's an honorable conquest figuring out how the length method works, but you should probably avoid using the length method.

Counting number frequency with StringTokenizer

How can I use StringTokenizer to count how many times a number is present in a String if the numbers are separated with "_"? The String has to be entered through the command line.
For example if user enters:
1_3_34_12_1_2_34
the output will be
1_2, 3_1, 34_2, 2_1, 12_1
Here is an example of what you can do
String input = "1_3_34_12_1_2_34";
String[] numbers = input.split("_");
Arrays.sort(numbers);
int count = -1;
String last = numbers[0];
for (String n : numbers) {
count++;
if (n.equals(last)) continue;
System.out.print(last + '_' + count + ',');
last = n;
count = 0;
}
count++;
System.out.println(last + '_' + count);
prints
1_2,12_1,2_1,3_1,34_2
Hint: The order suggests you should use a LinkedHashMap<String, Integer>

Categories