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>
Related
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 :)
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)
public static String number(String words) {
int length = words.length;
int total = 0;
while(int index < length) {
total = total + 1;
index = index + 1;
}
}
String output;
output = total + " word";
return output;
}
Example output for this would be:
numberOfWords("Hello whats up?")
3 word
This would work for all proper sentences but I have to account for bad input for example:
"Hi my name is bob"
, this would be like thirty plus words. Also
" "
, should be 0 words. Is there any simple way to make the first example to "hi my name is bob" ?
you can do something like this :
String trimmed = text.trim();
int words = trimmed.isEmpty() ? 0 : trimmed.split("\\s+").length;
or (simplest way):
use str.replaceAll("\\s+"," ");
Simplest will work in every case
String word = "Hi my name is bob";
word = word.replaceAll("\\s+", " ");
String count [] = word.split(" ");
System.out.println(count.length);
I have a string:
String text = "Nothing right in my brain. Nothing left in my brain"
I want to create a new string text2 that has 2-4 random new line from previous, such as:
"Nothing \n right \n in my brain. \n Nothing left in my brain"
or
"Nothing right in \n my brain. Nothing left in \n my brain"
How to create a new string with random new line between the words?
I am thinking to get the index of whitespace, in order to insert new line after random whitespace. But I only keep getting the first whitespace index.
Anyone know better approach to solve this? Thank you.
There are three stages to your problem, splitting the String, inserting randomness and using them together...
Splitting a String
Break it into words with String.split(), which creates an array of Strings (in this case words) by spaces.
String[] words = text.split(" "); //Split by spaces
then rebuild your String with newlines added for instance:-
StringBuiler sb = new StringBuilder();
for (String word : words)
{
sb.append(word + "\n");
}
String text2 = sb.toString();
In this case you will insert a newline in between every word and save the result in text2.
Inserting Randomness
You could just create a Random object...
Random random = new Random();
Then use it in the code that inserts your newline, like so...
//Randomly add or don't add a newline (Compacted with a ternary operator instead of an 'if')
sb.append(word + (random.nextBoolean() ? "\n" : ""));
Bringing it together (TLDR)
Then all you need to do is maintain a count of inserted newlines and limit them to that. So your code becomes:-
int requiredNewlines = random.nextInt(2 - 5) + 2; //Number between 2-4
for (String word : words) //For each word
{
sb.append(word); //Add it
if (requiredNewlines >= 0 && random.nextBoolean())
{
//Randomly add newline if we haven't used too many
sb.append("\n");
requiredNewlines--;
}
}
String text2 = sbAppen.toString();
Additionally
Although the randomness in this example fits your purpose here it is not the ideal implementation of random (as mentioned in the comments), in that there is more bias towards one appearing nearer the start of the String than the end and that there no chance of it appearing before the first word.
There is also another option of using StringTokenizer instead of String.split() which I much prefer but it doesn't deal with regex and is falling out of use, so I've changed my answer to use String.split()
First you need a new random from 2-4:
int max = 4;
int min = 2;
Random rand = new Random();
int randomNum = rand.nextInt((max - min) + 1) + min;
After split string into words:
String[] words = text.split(" ");
Then, get 4 different numbers from 1 to words.length
ArrayList<Integer> randomPositions = new ArrayList<Integer>(randomNum);
max = words.length;
min = 1;
for (int count = 0; count < randomNum; count ++) {
int random = rand.nextInt((max - min) + 1) + min;
if (randomPositions.contains(random)) count --;
else randomPositions.add(random);
}
Finally put \n in positions when rebuilding the array:
StringBuilder result = new StringBuilder();
for (int count = 0; count < max; count ++) {
result.append(words[count]);
if (randomPositions.contains(count))
result.append("\n");
else
result.append(" ");
}
Check this working demo
Output1:
Nothing right in my
brain. Nothing
left in my brain
Output2:
Nothing right
in my brain. Nothing left
in my
brain
Output3:
Nothing right in my brain. Nothing left
in my brain
You can only get either the first index using indexOf() or the last index using lastIndexOf() methods.
But as a workaround you can use text.indexOf(" ", randomInt);. This will give you the first index of " " after the randomInt index.
String str = "Nothing right in my brain. Nothing left in my brain";
String[] split = str.split(" ");
for (int i = 0; i < split.length; i++) {
int flag = ((int) (Math.random() * 10)) % 2;
if (flag == 0) {
split[i] = split[i] + "\n";
}
}
str="";
for (int i = 0; i < split.length; i++) {
str += split[i]+" ";
}
First you could get a random index where to put the new line
Random rand = new Random();
String[] words = text.split(' ');
for(int i = 0; i < 3; i++){
int index = rand.nextInt(words.length());
words[index] = "\n" + words[index];
}
text = Arrays.toString(words);
and at the end you will have 3 new lines on random places in your text string
EDIT: one way the result to be without commas is this one:
text = Arrays.toString(words).replaceAll(", ", " ");
Generate String with insertions at different positions:
public static String generateString(String inputString, String delimiter,
String insString, int[] insIndexes) {
String[] splittedString = inputString.split(delimiter);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < splittedString.length; i++) {
sb.append(splittedString[i]);
if (Arrays.binarySearch(insIndexes, i + 1) >= 0)
sb.append(delimiter + insString);
sb.append(delimiter);
}
return sb.toString();
}
Invocation Part :
String inputString = "Nothing right in my brain. Nothing left in my brain";
String delimiter = " "; // input String delimiter
String insString = "\n"; // insertion String
int[] insIndexes = { 2, 4, 6, 8 }; // insertion indexes
String outputString = generateString(inputString, delimiter, insString, insIndexes);
I'm relatively new to java and have a problem with a program I'm working on. The main idea of the program is to be given a document an calculate the total amount of words in the document, average number of words per line and vowels per line.
I've come up with a starting point but don't really know how to continue.
import java.io.*;
public class Example {
public static void main(String[] args) throws IOException {
int vowelCount = 0, wordsAvg = 0, wordsCount = 0, a;
char ch;
String line;
int vowels1 = 0, vowels2 = 0, vowels3 = 0, vowels4 = 0, vowels5 = 0, vowels6 = 0, vowels7 = 0, vowels8 = 0, vowels9 = 0, vowels10 = 0;
BufferedReader in ;
in = new BufferedReader(new FileReader("message.txt"));
line = in .readLine();
}
for (int i = 0; i < line.length(); i++) {
ch = line.charAt(i);
if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') vowels1++;
}
{
System.out.println(line);
System.out.println("--------------------------------------------");
System.out.println("Total number of words: " + wordsCount);
System.out.println("Average number of words per line: " + wordsAvg);
System.out.println("The number of vowels in line 1 is: " + vowels1);
System.out.println("The number of vowels in line 2 is: " + vowels2);
System.out.println("The number of vowels in line 3 is: " + vowels3);
System.out.println("The number of vowels in line 4 is: " + vowels4);
System.out.println("The number of vowels in line 5 is: " + vowels5);
System.out.println("The number of vowels in line 6 is: " + vowels6);
System.out.println("The number of vowels in line 7 is: " + vowels7);
System.out.println("The number of vowels in line 8 is: " + vowels8);
System.out.println("The number of vowels in line 9 is: " + vowels9);
System.out.println("The number of vowels in line 10 is: " + vowels10);
line = in .readLine();
}
}
So far I have the program reading the file and counting the vowels for the first line but I dont really know how to loop through each other line.
Also I need the output to show as I have it pre-setup.
Any help is appreciated, trying to keep it as simple as possible would be great.
You may read a file in java using BufferedReader until the line is not null. While reading a file you may call appropriate method to calculate number of word, vowel etc -
BufferedReader br = new BufferedReader(new FileReader("file.txt"));
try {
String line = br.readLine();
while (line != null) {
int wordsPerLine = countWord(line);
int vowelsPerLine = countVowel(line);
line = br.readLine();
}
} finally {
br.close();
}
Now you can write your countWord(String line) method like this -
//this method will count word for per input line
public int countWords(String line)
{
String words[]=line.split(" ");
int count=words.length;
return count;
}
And you may also count vowels per line like this -
public int coutnVowels(String line){
int count =0;
for(int i=0; i<line.length; i++){
char currentChar = line.CharAt(i);
if(currentChar=='a'||currentChar=='e'||currentChar=='i'||currentChar=='o'
currentChar=='u'){
count++;
}
}
return count;
}
Looping through the file
BufferedReader br;
String line = br.readLine();
while (line != null)
{
... // do stuff to file here
line = br.readLine();
}
Another tip is to use the right datatype to store the vowels for each line.
Since we do not know how many lines there will be in the file an ArrayList would be useful:
import java.util.ArrayList;
ArrayList<Integer> vowels = new ArrayList<Integer>()
while (line != null) {
vowels.add(countVowels(line));
}
This will store the vowels for each line in the array list.
then to display the counts you loop over the vowels array list, loop over the arraylist:
int lineNo = 1;
for(Integer nrVowels : vowels) {
System.out.println("The number of vowels in line "
+ lineNo + " is: "+ nrVowels);
}
EDITED
Scanner myScanner = new Scanner(new File(fileName));
int nbLines = 0, nbWords = 0, nbVowels = 0;
while(myScanner.hasNextLine()) {
line = myScannner.nextLine();
nbWords += countWords(line); // the method in Razib's post
++nblines; // increment number of lines
nbVowels += coutnVowels(line); // again use the method Razib gave you.
}
myScanner.close();
//nbWords now contains the number of words in the file.
// nblines is the number of line in the file.
// and nbVowels the total number of vowels in the file.
int avrg = nbWords / nblines; //average words per line.
this should work.
you should be able to do the rest yourself ;)