Learning Algorithms with JS, Python and Java 4: MaxChar
Tags: algorithms, beginners, learning, java
Published: 2018-08-06 15:36:20

---
title: Learning Algorithms with JS, Python and Java 4: MaxChar
published: true
description: 
tags: algorithms, beginners, learning, java
---

This is the fourth article of my attempts to follow Stephen Grider's [Udemy course](https://www.udemy.com/coding-interview-bootcamp-algorithms-and-data-structure/) in three different languages.

First I quote todays's question:
> --- Directions
> Given a string, return the character that is most
> commonly used in the string.
> --- Examples
> maxChar("abcccccccd") === "c"
> maxChar("apple 1231111") === "1"

JavaScript:
```
function maxChar(str) {
    const charMap = {};
    let max = 0;
    let maxChar = '';

    for (let char of str) {
        if (charMap[char]) {
            charMap[char]++
        } else {
            charMap[char] = 1;
        }
    }

    for (let char in charMap) {
        if (charMap[char] > max) {
            max = charMap[char];
            maxChar = char;
        }
    }

    return maxChar;
}
```

Stephen rewrites the first for loop as:
```
    for (let char of str) {
        charMap[char] = charMap[char] + 1 || 1;
    }
```
This is possible because `anObject['nonexistentKey']` returns `undefined`, `undefined + 1` return `NaN`, which is falsy.

Python:
```
def max_char(str):
    char_map = {}
    max = 0
    max_char = ''

    for char in str:
        char_map.setdefault(char, 0)
        char_map[char] += 1

    for char in char_map:
        if char_map[char] > max:
            max = char_map[char]
            max_char = char

    return max_char
```
In Python, you can't just try `char_map[char] += 1` as in JS, because it would throw a KeyError if the key doesn't exist yet.

More concisely:
```
def max_char(str):
    char_map = {}

    for char in str:
        char_map.setdefault(char, 0)
        char_map[char] += 1

    return max(char_map, key=char_map.get)
```
Source: https://stackoverflow.com/questions/268272/getting-key-with-maximum-value-in-dictionary
`max(char_map, key=char_map.get)` is the same as `max(char_map.keys(), key=char_map.get)`.
`key=char_map.get` is needed to find the (key, value) tuple pair in the dictionary whose *value* is the largest. `max({'a': 2, 'b': 1})` returns 'b'.

Java:
```
import java.util.HashMap;
import java.util.Map;

public static char maxChar2(String str) {
	Map<Character, Integer> charMap = new HashMap<>();

	for (char chr : str.toCharArray()) {
		Integer chrCount = charMap.get(chr);
		if (chrCount == null) {
			chrCount = 0;
		}
		charMap.put(chr, chrCount + 1);
	}

	int max = 0;
	char maxChar = '\0';

	for (Map.Entry<Character, Integer> entry : charMap.entrySet()) {
		int value = entry.getValue();
		if (value > max) {
			max = value;
			maxChar = entry.getKey();
		}
	}

	return maxChar;
}
```
Using Stream:
```
public static char maxChar(String str) {
	Map<Character, Long> charMap = str.chars()
			.mapToObj(i -> (char) i)
			.collect(Collectors.groupingBy(
					c -> c, Collectors.counting()));
	
	return charMap.entrySet().stream()
			.collect(Collectors.groupingBy(
					Map.Entry::getValue,
					TreeMap::new,
					Collectors.mapping(
							Map.Entry::getKey, Collectors.toList())))
			.lastEntry()
			.getValue()
			.get(0);
}
```
The return statement can be made simpler:
```
	return charMap.entrySet().stream()
			.max(Map.Entry.comparingByValue())
			.get()
			.getKey();
```

References:
https://codereview.stackexchange.com/questions/133058/print-max-occurring-character-in-a-string
https://stackoverflow.com/questions/48280361/how-to-count-occurrences-for-each-value-in-multimap-java
https://stackoverflow.com/questions/42060294/using-java8-stream-to-find-the-highest-values-from-map