Hello, I've had a good search to see if anything else was posted in relevance with this, but can't find anything that suits my exact needs.

I've been given a Java assignment to take in a file, and read how many characters it has (omitting white-space and new lines) and then to display the top ten most occurring characters.

Now, I can display how many characters, and how many of each character appears, but I'm finding it difficult to display only the top 10 and in descending order (the one occurring most frequently to the least frequently occurring one)

Here's what I have so far.

mport java.io.*;
import java.lang.reflect.Array;
import java.util.*;

public class FrequencyAgain {

    public static void main(String[] args) throws Exception {
        
        //Set up file to be read in.
        BufferedReader br = new BufferedReader(new FileReader("C:/Users/Dave/Desktop/myfile.txt"));
        
        //Set up attributes
        String strLine = "";
        String str = "";
        
        //Set true if character case if not an issue.
        Boolean charCase = false;
        
        //Join strings together, ommitting returns and new lines.
        while ((strLine = br.readLine()) != null) {str += strLine;}

        //Remove whitespace so characters can be counted.
        String st = str.replaceAll(" ", "");
        
        //Changes to lowercase if character case is insensitive.
        if(charCase == true) {
            st = st.toLowerCase();
        }
        
        //assign letters to array
        char[] letters = st.toCharArray();
        
        //Print out total letters and occurance of each letter
        System.out.println("Total Characters: " + st.length());
        System.out.println("Character   Total");
        
        //Cycle through each letter
        for(int counter = 0; counter < letters.length; counter++) {
            char character = letters[counter];
            int count = 0;
            
            //Counter for letters and how often they occur.
            for(int i = 0; i < letters.length; i++) {
                if(character == letters[i]) {
                    count++;}
            }
            
            boolean flag = false;
            for (int j = counter - 1; j >= 0; j--) {
                if (character == letters[j]){
                    flag = true;}
            }
            
            if (!flag) {
                System.out.println(character + "   (" + count + ')');}
                }
        }
}

Thanks for anyone's help in advance! :)

you could create an object which has two variables:
int number
and
int numberOccursNTimes

while next number
read number
check in stored numbers whether number already occured
if yes
add 1 to numberOccursNTimes for number
else
create new occurence with number as number and 1 as numberOccursNTimes
end-if
end-while

// at this point you have all the numbers with their occurences in a list

orderListBy numberOccursNTimes

print first ten members of the list

Would you be able to give me a coded example of how to do that. I'm a bit lost.

Thanks!

public class NumberOccured{

int number;
int numberOccursNTimes;

public NumberOccured(int number){
  this.number = number;
  this.numberOccursNTimes = 1;
}

// this is to be called when you find a next occurence of the number stored
public augmentOccurences(){
  this.numberOccursNTimes = this.numberOccursNTimes + 1;
}

public int getNumberOccursNTimes(){
  return numberOccursNTimes;
}

public int getNumber(){
  return number;
}
}

in the main class, create an ArrayList of NumberOccured elements.
write a boolean method which takes an int as a parameter, and returns true if in the ArrayList there is an element whose getNumber() method returns a value equal to your parameter, false otherwise.
if it was true, you also augment the numberOccurences of that element, otherwise, you create a new NumberOccured instance, use the same int as parameter and add this object to the ArrayList.

when you've entered all your numbers, write a method that sorts the elements in the ArrayList, based on the value of numberOccursNTimes

I'm afraid I'm still having difficulties with how to continue with this program.

write a boolean method which takes an int as a parameter, and returns true if in the ArrayList there is an element whose getNumber() method returns a value equal to your parameter, false otherwise.
if it was true, you also augment the numberOccurences of that element, otherwise, you create a new NumberOccured instance, use the same int as parameter and add this object to the ArrayList.

Make a main class that calls the methods posted by stultuske

Do you know how to use separate classes?

Yes, I've done that. It's the whole boolean method part I'm confused about.

I also don't know where I'd call these methods in my program...? Or where in my program I'd put the boolean method and array list...

what whole boolean method?

you loop over the arraylist and then
if element.getNumber == number
return true(or you can return the index)
and after the loop, you put
return false(or -1, to indicate the number was not found)

well, just try and post what you have here. We're not going to spoonfeed youcode

At the loop, whenever the boolean equals true the number of times the value has appeared in the Arraylist will be added by one(call augmentOccurences) else new number has appeared then add the number in the ArrayList

I believe stultuske has explained it well already

add the number in the ArrayList

but don't forget to create a new instance of the class I provided earlier and to add that instance, if you try to add an int to an ArrayList, you might get another result entirely :)

commented: right...like I said you already gave a complete solution +4
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.