如何使用 Map 按字符串中出现的次数对字符进行排序?
How to sort a character by number of occurrences in a String using a Map?
我编写了代码来计算给定字符串中每个字符的频率并显示它:
Map<Character, Integer> occurrences = new HashMap<>();
char[] chars = str2.toCharArray();
for (char character : chars) {
Integer integer = occurrences.get(character);
occurrences.put(character, integer);
if (integer == null) {
occurrences.put(character, 1);
} else {
occurrences.put(character, integer + 1);
}
}
System.out.println(occurrences);
现在我想修改我的代码,让它显示按频率排序的字符。从出现频率最高的字符开始,然后是出现频率第二高的字符,然后是出现频率第三的字符,依此类推。
例如字符串 Java
应按以下顺序显示为字符频率:a=2, j=1, v=1
.
如果您使用 Java 的 TreeMap
Map 实现,它将保持您的 values 排序通过 键.
还有一个构造函数,如果您需要自己的排序方式,您可以在其中传递 Comparator
的自定义实现。
考虑使用 TreeMap ( https://docs.oracle.com/javase/7/docs/api/java/util/TreeMap.html )
TreeMap is a map implementation that keeps its entries sorted
according to the natural ordering of its keys.
您可以参考以下代码参考。
import java.util.Map;
import java.util.TreeMap;
class Test {
static void characterCount(String inputString)
{
TreeMap<Character, Integer> charCountMap = new TreeMap<Character, Integer>();
char[] strArray = inputString.toCharArray();
for (char c : strArray) {
if (charCountMap.containsKey(c)) {
charCountMap.put(c, charCountMap.get(c) + 1);
}
else {
charCountMap.put(c, 1);
}
}
for (Map.Entry entry : charCountMap.entrySet()) {
System.out.println(entry.getKey() + "=" + entry.getValue());
}
}
public static void main(String[] args)
{
String str = "welcometoWhosebug";
characterCount(str);
}
}
输出 :
a=1
c=2
e=3
f=1
k=1
l=2
m=1
o=4
r=1
s=1
t=2
v=1
w=2
像这样尝试。
String str = "To be or not to be, that is the question";
- 根据字符和计数流式传输字符和组。
- 然后重新流式传输条目集以按 值
排序
- 指定
LinkedHashMap
以保留排序顺序。
条目首先按值(计数)排序。如果计数等于它们,则按键排序。
Map<Character, Long> map = str.chars()
.mapToObj(c -> Character.valueOf((char) c))
.collect(Collectors
.groupingBy(c -> c, Collectors.counting()))
.entrySet().stream()
.sorted(Entry.<Character, Long>comparingByValue()
.reversed().thenComparing(Entry.comparingByKey()))
.collect(Collectors.toMap(Entry::getKey,
Entry::getValue, (a, b) -> a,
LinkedHashMap::new));
map.entrySet().forEach(System.out::println);
版画
=9
t=6
o=5
e=4
b=2
h=2
i=2
n=2
s=2
,=1
T=1
a=1
q=1
r=1
u=1
您可以收集两张地图:第一张汇总数量的地图,然后对其进行排序并收集第二张排序后的地图。在这种情况下,如果数量相等,则使用遇到顺序:
String str = "JavaProgrammingLanguage";
Map<Character, Integer> occurrences = str.codePoints()
// Stream<Character>
.mapToObj(ch -> (char) ch)
// collect to a map in insertion
// order, summing up the quantities
.collect(Collectors.toMap(
// key - lowercase character
Character::toLowerCase,
// value - quantity '1'
ch -> 1,
// summing quantities
Integer::sum,
// insertion order
LinkedHashMap::new))
// Stream<Map.Entry<Character,Integer>>
.entrySet().stream()
// sort by quantity in reverse order
.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
// collect into a sorted map
.collect(LinkedHashMap::new,
(map, entry) -> map.put(entry.getKey(), entry.getValue()),
HashMap::putAll);
// output
System.out.println(occurrences);
// {a=5, g=4, r=2, m=2, n=2, j=1, v=1, p=1, o=1, i=1, l=1, u=1, e=1}
另请参阅:The intersection of all combinations of n
sets
我编写了代码来计算给定字符串中每个字符的频率并显示它:
Map<Character, Integer> occurrences = new HashMap<>();
char[] chars = str2.toCharArray();
for (char character : chars) {
Integer integer = occurrences.get(character);
occurrences.put(character, integer);
if (integer == null) {
occurrences.put(character, 1);
} else {
occurrences.put(character, integer + 1);
}
}
System.out.println(occurrences);
现在我想修改我的代码,让它显示按频率排序的字符。从出现频率最高的字符开始,然后是出现频率第二高的字符,然后是出现频率第三的字符,依此类推。
例如字符串 Java
应按以下顺序显示为字符频率:a=2, j=1, v=1
.
如果您使用 Java 的 TreeMap
Map 实现,它将保持您的 values 排序通过 键.
还有一个构造函数,如果您需要自己的排序方式,您可以在其中传递 Comparator
的自定义实现。
考虑使用 TreeMap ( https://docs.oracle.com/javase/7/docs/api/java/util/TreeMap.html )
TreeMap is a map implementation that keeps its entries sorted according to the natural ordering of its keys.
您可以参考以下代码参考。
import java.util.Map;
import java.util.TreeMap;
class Test {
static void characterCount(String inputString)
{
TreeMap<Character, Integer> charCountMap = new TreeMap<Character, Integer>();
char[] strArray = inputString.toCharArray();
for (char c : strArray) {
if (charCountMap.containsKey(c)) {
charCountMap.put(c, charCountMap.get(c) + 1);
}
else {
charCountMap.put(c, 1);
}
}
for (Map.Entry entry : charCountMap.entrySet()) {
System.out.println(entry.getKey() + "=" + entry.getValue());
}
}
public static void main(String[] args)
{
String str = "welcometoWhosebug";
characterCount(str);
}
}
输出 :
a=1
c=2
e=3
f=1
k=1
l=2
m=1
o=4
r=1
s=1
t=2
v=1
w=2
像这样尝试。
String str = "To be or not to be, that is the question";
- 根据字符和计数流式传输字符和组。
- 然后重新流式传输条目集以按 值 排序
- 指定
LinkedHashMap
以保留排序顺序。
条目首先按值(计数)排序。如果计数等于它们,则按键排序。
Map<Character, Long> map = str.chars()
.mapToObj(c -> Character.valueOf((char) c))
.collect(Collectors
.groupingBy(c -> c, Collectors.counting()))
.entrySet().stream()
.sorted(Entry.<Character, Long>comparingByValue()
.reversed().thenComparing(Entry.comparingByKey()))
.collect(Collectors.toMap(Entry::getKey,
Entry::getValue, (a, b) -> a,
LinkedHashMap::new));
map.entrySet().forEach(System.out::println);
版画
=9
t=6
o=5
e=4
b=2
h=2
i=2
n=2
s=2
,=1
T=1
a=1
q=1
r=1
u=1
您可以收集两张地图:第一张汇总数量的地图,然后对其进行排序并收集第二张排序后的地图。在这种情况下,如果数量相等,则使用遇到顺序:
String str = "JavaProgrammingLanguage";
Map<Character, Integer> occurrences = str.codePoints()
// Stream<Character>
.mapToObj(ch -> (char) ch)
// collect to a map in insertion
// order, summing up the quantities
.collect(Collectors.toMap(
// key - lowercase character
Character::toLowerCase,
// value - quantity '1'
ch -> 1,
// summing quantities
Integer::sum,
// insertion order
LinkedHashMap::new))
// Stream<Map.Entry<Character,Integer>>
.entrySet().stream()
// sort by quantity in reverse order
.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
// collect into a sorted map
.collect(LinkedHashMap::new,
(map, entry) -> map.put(entry.getKey(), entry.getValue()),
HashMap::putAll);
// output
System.out.println(occurrences);
// {a=5, g=4, r=2, m=2, n=2, j=1, v=1, p=1, o=1, i=1, l=1, u=1, e=1}
另请参阅:The intersection of all combinations of n
sets