Couting Word Frequency - java

public static void CountWordFrequency(ArrayList<String> UserString) {
//creating an array list to store every word
//each element in the UserString is one line
ArrayList<String> words_storage = new ArrayList<String>();
String words[]= {};
for(int i=0;i<UserString.size();i++) {//this is outer loop to access every line of the ArrayList
//we need to split the line and put them inside the array String
words = UserString.get(i).split("\\s");
//we still need to work with the "\'" , the upper case, and the dot and comma
for(int j=0;j<words.length;j++) {
for(int k=0;k<words[j].length();k++) {//access every character of one word
if(Character.isUpperCase(words[j].charAt(k))) {//first I want to convert them to Lower Case first
words[j]=words[j].toLowerCase();
}
if(!Character.isLetterOrDigit(words[j].charAt(k)) && words[j].charAt(k)!=',' && words[j].charAt(k)!= '.') {
//I am separating the comma and dot situations with the ' \' '
//need more work on this
if(words[j].compareTo("can't")==0) {
words[j]=words[j].replace(words[j].charAt(k), '\0');
words[j]=words[j].replace(words[j].charAt(k+1), '\0');
words[j] = "can";
words_storage.add("not");
}
else {
words[j]=words[j].replace(words[j].charAt(k), '\0');
words_storage.add("is");
}
}
//now if the that character is comma or dot
if(words[j].charAt(k)==',' ||words[j].charAt(k)=='.') {
words[j]=words[j].replace(words[j].charAt(k), '\0');
}
}//done with one-word loop
}
//now we need to store every element of the String Array inside the array list
for(int j=0;j<words.length;j++) {
words_storage.add(words[j]);
}
}//this is the end of the outer loop
//since it's harder to change the content of element in array list compared to array
//we need to store elements in another array
String[] array = new String[words_storage.size()];
for(int a =0;a<words_storage.size();a++) {
array[a] = words_storage.get(a);
}
//now when we are done with storing elements, we need to sort alphabetically
for(int a=0;a<array.length;a++) {
for(int b = a+1;b<array.length;b++) {
if(array[a].compareTo(array[b])>0) {
String temp = array[a];
array[a] = array[b];
array[b] = temp;
}
}
}
//now we count the frequency of each element in the Array array
int marker = 0;//marker will help me skip the word that already counted in the frequency
for(int x =0;x<array.length;x=marker) {
int counter = 1;
for(int y =x+1; y< array.length;y++) {
if(array[x].compareTo(array[y])==0) {//if they have the same content then we increase the counter and mark the y
counter++;
marker = y+1;
}
}
if(counter==1) {//if we did not find any similar word, we need to increase the marker by one to check on the next word
marker++;
}
System.out.println(array[x]+":"+counter); //now just print it out
}
}
Hey guys
I am trying to count word frequency in the given input which has many lines. I stored it in an ArrayList and put it as a paramenter.
First of all, I try to sort them aphabetically first
Right now, I am trying to remove the character ' in the word can't. But it didn't seem to work. so I tried using replace method but it will leave a blank when I replace it with '\0'
Hopefully, I got some solutions. Thanks in advance.

Just use compareTo() or compareToIgnoreCase() method to find the word.

Related

How do i print one element of an arraylist to uppurcase while the other elements lowercase

the elements of array list need to be printed one by one, which one be printed uppsercase other lowercase
public static void main(String[] args) {
String[] days = {"monday","saturday","tuesday","sunday","friday"};
ArrayList<String> weekdays = new ArrayList();
weekdays.add("monday");
weekdays.add("thursday");
weekdays.add("wednesday");
weekdays.add("surtaday");
weekdays.add("tuesday");
weekdays.add("sunday");
weekdays.add("friday");
// Loop through the ArrayList, printing out "sunday" elements in
for(int i=0;i<weekdays.size();i++){
System.out.println(weekdays.get(i));
}
}
Can you not add the word to the list as an uppercase letter? If not, depending on which word you want to capitalize, i'm assuming the first one, you can do this:
for(int i=0;i<weekdays.size();i++){
if(i == 0){
System.out.println(weekdays.get(i).toUpperCase());
}else{
System.out.println(weekdays.get(i));
}
}
Similarily, if you want to do the second word:
for(int i=0;i<weekdays.size();i++){
if(i == 1){ //change this from 0 to 1
System.out.println(weekdays.get(i).toUpperCase());
}else{
System.out.println(weekdays.get(i));
}
}
and so on...
You need to change the value in the if statement depending on the word you want to capitalize

Replace characters in string if there a multiple of the same character in Java

So I have been learning Java for a little over a month now, and I have a hang man game that I am making but I am having trouble with replacing characters in my string. I have it written so you have two strings, one is called "word" which contains the word to be guessed and the other is called "clone" which is a clone of the word that replaces all the characters with underscores. Then as you guess a letter it checks the string "word" to make sure it contains it, and if it does it replaces the underscore in "clone" with that letter.
while (this.guessesLeft >= 0) {
char letter;
int letterIndex;
getGuess();
if(this.word.contains(this.letterGuessed)) {
StringBuilder newString = new StringBuilder(this.clone);
letterIndex = this.word.indexOf(this.letterGuessed);
letter = this.word.charAt(letterIndex);
newString.setCharAt(letterIndex, letter);
this.clone = newString.toString();
} else {
this.guessesLeft--;
}
printGameBoard();
}
The problem that I'm having is that if you guess a letter and the string contains two of a character it only shows one. For example, here is my output if the word "burrito" is used.
Guess a letter: r
bur____
You have 5 guess left before you die!
Guess a letter: i
bur_i__
You have 5 guess left before you die!
Guess a letter: r
bur_i__
You have 5 guess left before you die!
How would I edit my game logic so that it if the letter "r" is guessed it puts both R's in the string and not just one? Thanks in advance for the help!
You need to look for all the indexes for your letter, then replace them all.
At the moment you only look for the first one.
To find all indexes, look for a first occurrence of the letter, then if you find one (indexOf returns a positive value), keep looking from that last position using the indexOf(int ch, int fromIndex) method until you have found them all (indexOf returns -1).
Here is an example:
if(this.word.contains(this.letterGuessed)) {
// look for an occurrence,
// if you have one, keep looking for others until you have them all (ie: index = -1)
List<Integer> indexes = new ArrayList<>();
int index = this.word.indexOf(this.letterGuessed);
while (index >= 0) { // <- that will loop until the indexOf returns a -1
indexes.add(index);
index = this.word.indexOf(this.letterGuessed, index+1);
}
// replace at all the found indexes
StringBuilder newString = new StringBuilder(this.clone);
for(int letterIndex : indexes) {
char c = this.word.charAt(letterIndex);
newString.setCharAt(letterIndex, c);
}
this.clone = newString.toString();
} else {
this.guessesLeft--;
}
You could also do that in one go, without holding the indexes in a list:
if(this.word.contains(this.letterGuessed)) {
StringBuilder newString = new StringBuilder(this.clone);
int index = this.word.indexOf(this.letterGuessed);
while (index >= 0) {
char c = this.word.charAt(index);
newString.setCharAt(index, c);
index = this.word.indexOf(this.letterGuessed, index+1);
}
this.clone = newString.toString();
System.out.println("clone = " + clone);
} else {
this.guessesLeft--;
}

How can I navigate through a 2-d array and shuffle the words within that array?

So I need help with this. I'm working with two-dimensional arrays and so what I'm trying to do is to navigate through the 2-d arrays in a row (starting at the top left of the array like you are reading a paragraph).
I trying to write a method that returns the array with the following rules:
1) If the word begins with a vowel (a, e, i, o, u) : swap the word with the previous word on the same row
2) If the word is the first word on the row, then swap it with the word just above it; however, if the word is on the first row, then no swapping should occur.
3) If the word begins with a consonant, then swap the first and last characters of the word.
Ex. 2-dim array:
rice , egg, room
apple, java, owl
Converted:
apple, eicr, moor
egg, owl, avaj
This is what I have so far:
I've got the tester class all set up and ready but I having trouble setting up the methods in the class below. This is essential what I need guidance for.
public class WordShuffle
{
// Use this method signature
// The parameter is a 2-dim array of words
// The method will return a 2-dim array of shuffled words
public String[][] shuffleWords(String[][] words)
{
}
}
Tester Class:
public class WordShuffleTester
{
// Don't change this tester except to change the values in the 2-dim array
public static void main(String[] args)
{
// This is the 2-dim array to test your method
String[][] words = {{ "doom", "candy", "apple"},
{"orange", "energy", "rat"},
{ "mad", "test", "cool"},
{ "red", "blue", "drain"}};
WordShuffle shuffler = new WordShuffle();
String[][] mixedUpWords = shuffler.shuffleWords(words);
// The following will print out each element of the returned array
for (int r=0; r < mixedUpWords.length; r++)
{
for (int c=0; c < mixedUpWords[r].length; c++)
{
System.out.print(mixedUpWords[r][c] + "\t");
}
System.out.println(" ");
}
}
}
If anyone could help me further with this it would be much obliged!
I was bored enough to give this a shot, but in the future try to at least attempt to solve the problem yourself (your shuffleWords method was completely empty).
public String[][] shuffleWords(String[][] words)
{
String vowels = "aeiou";
String temp = "";
for (int i=0; i < words.length; i++)
{
for (int j=0; j < words[i].length; j++)
{
if(vowels.contains(words[i][j].substring(0,1)) && j > 0){
temp = words[i][j];
words[i][j] = words [i][j-1];
words[i][j-1] = temp;
}
if(j == 0 && i > 0){
temp = words[i][j];
words[i][j] = words [i-1][j];
words[i-1][j] = temp;
}
if(!vowels.contains(words[i][j].substring(0,1))){
String s = words[i][j];
temp = s.substring(1,s.length()-1);
String first = s.substring(0,1);
String last = s.substring(s.length()-1,s.length());
words[i][j] = last + temp + first;
}
}
}
return words;
}
While this code works, it is important to note that when words are moved (due to the 1st or 2nd rule) words that begin with consonants may have the first and last letter swapped multiple times. Not sure if this is the intended effect, but some adjustments may need to be made to the order that these tasks are performed. Here is the output when I ran it using your WordShuffleTester
//Input:
doom candy apple
orange energy rat
mad test cool
red blue drain
//Output:
orange apple candy
mad mood tar
red test looc
energy elub nraid

Ascending ArrayList is adding element in wrong order

I have a list that is comparing the column elements of an ArrayList (essentially, the string word of an ArrayList that contains string lines).
I was able to read the column part correctly, but there's an error for my insertion method (which I'm doing recursively).
For instance, when it finds a word that is smaller than the previous word, instead of inserting it before the bigger word, it inserts it at the beginning of the ArrayList. I'm not exactly sure why this is, as I seem to be following the steps for insertion exactly what my notes say. Can anyone see why this is happening?
//line is just a string separated by commas
private void insertSorted(String line){
//memFile is the ArrayList
if(memFile.isEmpty()){
memFile.add(0,line);
}
else{
for(int i = memFile.size() - 1; i >=0 ; i--){
int index = i;
String lineList = memFile.get(i);
String[] tokens = line.trim().split(",");
String lineList = memFile.get(i);
String[] tokens1 = lineList.trim().split(",");
//column is the part I want to compare of the tokenized string
while(index >= 0){
if((tokens[column]).compareTo(tokens1[column]) < 0)
index--;
}
break;
}
memFile.add(index+1,line);
System.out.println("memFile is " + memFile);
}//for
}//else
}//insertSorted
It's printing out:
3
1
2
2
4
1
as
1
2
2
3
1
4
Edit:
Say I had an ArrayList memfile, and it contained the strings:
" 1,DOG,Airplane"
" 3,HAT,Basket"
And I wanted to sort the third variables by alphabetically order. Then I would tokenize the string, and from the main method, I would call 2 (column is an instance variable I declared making this class). So, then it would search for tokens[col], or, equivalently, tokens[2].
You have a logic mistake in your method, what you are doing is comparing the line with the last value of the memFile instead of comparing the current index line of the memFile when reducing the index
Here i modified the method according to your required logic.
private void insertSorted(String line) {
// memFile is the ArrayList
if (memFile.isEmpty()) {
memFile.add(0, line);
} else {
int index = memFile.size() - 1;
String[] tokens = line.trim().split(",");
// column is the part I want to compare of the tokenized string
while (index >= 0) {
String lineList = memFile.get(index);
String[] tokens1 = lineList.trim().split(",");
if ((tokens1[column]).compareTo(tokens[column]) > 0) {
index--;
} else {
break;
}
}
memFile.add(index + 1, line);
System.out.println("memFile is " + memFile);
}
}
Hope it helps you

Java String Array Mergesort

Hi all I wrote a mergesort program for a string array that reads in .txt files from the user. But what I want to do now is compare both files and print out the words in file one and not in file two for example apple is in file 1 but not file 2. I tried storing it in a string array again and then printing that out at the end but I just cant seem to implement it.
Here is what I have,
FileIO reader = new FileIO();
String words[] = reader.load("C:\\list1.txt");
String list[] = reader.load("C:\\list2.txt");
mergeSort(words);
mergeSort(list);
String x = null ;
for(int i = 0; i<words.length; i++)
{
for(int j = 0; j<list.length; j++)
{
if(!words[i].equals(list[j]))
{
x = words[i];
}
}
}
System.out.println(x);
Any help or suggestions would be appriciated!
If you want to check the words that are in the first array but do not exist in the second, you can do like this:
boolean notEqual = true;
for(int i = 0; i<words.length; i++)
{
for(int j = 0; j<list.length && notEqual; j++)
{
if(words[i].equals(list[j])) // If the word of file one exist
{ // file two we set notEqual to false
notEqual = false; // and we terminate the inner cycle
}
}
if(notEqual) // If the notEqual remained true
System.out.println(words[i]); // we print the the element of file one
// that do not exist in the second file
notEqual = true; // set variable to true to be used check
} // the other words of file one.
Basically, you take a word from the first file (string from the array) and check if there is a word in file two that is equal. If you find it, you set the control variable notEqual to false, thus getting out of the inner loop for and not print the word. Otherwise, if there is not any word on file two that match the word from file one, the control variable notEqual will be true. Hence, print the element outside the inner loop for.
You can replace the printing statement, for another one that store the unique word in an extra array, if you wish.
Another solution, although slower that the first one:
List <String> file1Words = Arrays.asList(words);
List <String> file2Words = Arrays.asList(list);
for(String s : file1Words)
if(!file2Words.contains(s))
System.out.println(s);
You convert your arrays to a List using the method Arrays.asList, and use the method contains to verify if the word of the first file is on the second file.
Why not just convert the Arrays to Sets? Then you can simply do
result = wordsSet.removeAll(listSet);
your result will contain all the words that do not exist in list2.txt
Also keep in mind that the set will remove duplicates ;)
you can also just go through the loop and add it when you reached list.length-1.
and if it matches you can break the whole stuff
FileIO reader = new FileIO();
String words[] = reader.load("C:\\list1.txt");
String list[] = reader.load("C:\\list2.txt");
mergeSort(words);
mergeSort(list);
//never ever null
String x = "" ;
for(int i = 0; i<words.length; i++)
{
for(int j = 0; j<list.length; j++)
{
if(words[i].equals(list[j]))
break;
if(j == list.length-1)
x += words[i] + " ";
}
}
System.out.println(x);
Here is a version (though it does not use sorting)
String[] file1 = {"word1", "word2", "word3", "word4"};
String[] file2 = {"word2", "word3"};
List<String> l1 = new ArrayList(Arrays.asList(file1));
List<String> l2 = Arrays.asList(file2);
l1.removeAll(l2);
System.out.println("Not in file2 " + l1);
it prints
Not in file2 [word1, word4]
This looks kind of close. What you're doing is for every string in words, you're comparing it to every word in list, so if you have even one string in list that's not in words, x is getting set.
What I'd suggest is changing if(!words[i].equals(list[j])) to if(words[i].equals(list[j])). So now you know that the string in words appears in list, so you don't need to display it. if you completely cycle through list without seeing the word, then you know you need to explain it. So something like this:
for(int i = 0; i<words.length; i++)
{
boolean wordFoundInList = false;
for(int j = 0; j<list.length; j++)
{
if(words[i].equals(list[j]))
{
wordFoundInList = true;
break;
}
}
if (!wordFoundInList) {
System.out.println(x);
}
}

Categories

Resources