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