Home > Back-end >  Print words occurrences from bigger to smaller (No Streams) Java
Print words occurrences from bigger to smaller (No Streams) Java

Time:06-23

can you please give me advice on how to print word occurrences from bigger value to smaller? I've tried different methods, so I stopped on the Map, it gives me a much closer result.

public class InputOutput {

    private String wordsFrequency() {
        StringBuilder result = new StringBuilder();

        try {
            Map<String, Integer> map = new HashMap<>();
            BufferedReader reader = new BufferedReader(new FileReader("words.txt"));
            String words;

            while ((words = reader.readLine()) != null) {
                Scanner scan = new Scanner(words);
                while (scan.hasNext()) {
                    String word = scan.next();
                    if (map.containsKey(word))
                        map.put(word, map.get(word)   1);
                    else
                        map.put(word, 1);
                }
                scan.close();
            }
            reader.close();
            Set<Entry<String, Integer>> entrySet = map.entrySet();

            for (Entry<String, Integer> entry : entrySet) {
                result.append(entry.getKey()).append("\t").append(entry.getValue()).append("\n");
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        return result.toString();

    }

    public static void main(String[] args) {
        InputOutput requestedData = new InputOutput();

        System.out.println(requestedData.wordsFrequency());

    }
}

text file: the day is sunny the the the sunny is is is is is is

Should be:
is  7
the 4
sunny   2
day 1

What I have:
the 4
is  7
sunny   2
day 1

CodePudding user response:

I'm sure there's a cleaner way to do it, but without using streams here's what I came up with:

String src = "the day is sunny the the the sunny is is is is is is";

try (Scanner scanner = new Scanner(new StringReader(src))) {
    Map<String, Integer> map = new HashMap<>();
    while (scanner.hasNext()) {
        String word = scanner.next();
        map.merge(word, 1, (a, b) -> a   1);
    }
    Map<Integer, Collection<String>> cntMap = new TreeMap<>(Comparators.reverseOrder());
        
    for (Entry<String, Integer> entry : map.entrySet()) {
       Collection<String> list = cntMap.get(entry.getValue());
       if (list == null) {
           list = new TreeSet<>();
           cntMap.put(entry.getValue(), list);
       }
       list.add(entry.getKey());
    }

    for (Entry<Integer, Collection<String>> entry : cntMap.entrySet()) {
       System.out.println(entry.getValue()   " : "   entry.getKey());
    }
}

CodePudding user response:

List<Map.Entry<String, Integer>> frequencies = new ArrayList<>(map.entrySet());
frequencies.sort(Comparator.comparing(e -> e.getValue()).reversed());

A List may be sorted, or a TreeSet can be sorted (SortedSet) using a Comparator. Here with a function returning a Comparable value.

CodePudding user response:

You can generate a map Map<String, Integer> representing the frequency of each word.

Then create a list of entries of this map, sort it based on values in descending order.

And finally turn the sorted list of entries into a list of strings which you can print.

private static Map<String, Integer> wordsFrequency(String file) {
    
    Map<String, Integer> frequencies = new HashMap<>();
    
    try (var reader = Files.newBufferedReader(Path.of(file))) {
        String[] words = reader.readLine().split(" ");
        for (String word : words) {
        //  frequencies.merge(word, 1, Integer::sum); an equivalent of the lines below
            int count = frequencies.getOrDefault(word, 0);
            frequencies.put(word, count   1);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    
    return frequencies;
}

public static List<String> mapToSortedList(Map<String, Integer> map) {
    List<Map.Entry<String, Integer>> entries = new ArrayList<>(map.entrySet());
    // sorting the list of entries
    entries.sort(Map.Entry.<String, Integer>comparingByValue().reversed());
    
    List<String> result = new ArrayList<>();
    for (Map.Entry<String, Integer> entry :entries) {
        result.add(entry.getKey()   entry.getValue());
    }
    return result;
}
  • Related