[英]Java, how to sort char alphabetically in Comparator
我正在嘗試建立一個最大的字符堆。 先按頻率排序,如果頻率相同,再按字母排序。
Map<Character, Integer> map = new HashMap<>();
for(int i = 0; i < n; i++) {
char c = s.charAt(i);
map.put(c, map.getOrDefault(c, 0) + 1);
}
Queue<Character> pq = new PriorityQueue<>(new Comparator<Character>(){
@Override
public int compare(Character c1, Character c2){
if(map.get(c1) == map.get(c2)){
return c1 < c2 ? -1 : (c1 == c2 ? 0 : 1);
//return (char)c1 - (char)c2; same output
}
return map.get(c2) - map.get(c1);
}
});
for(char key : map.keySet()){
pq.offer(key);
System.out.println(key + " has freq " + map.get(key));
}
while(!pq.isEmpty()) {
System.out.print(pq.poll() + " ");
}
我將 26 個字母放入這個 maxheap 中,每個字母的頻率相同 5000。
但是 output 的順序是 'a'、'z'、'y'、'x'....、'c'、'b'。
我不明白為什么頻率為5000的output是這樣的。 我怎樣才能得到正確的訂單?
鑒於所有頻率都相同,您的 if 語句是錯誤的。 您可以使用內置方法來比較對象並返回結果
Integer f1 = map.get(c1);
Integer f2 = map.get(c2);
int x = f1.compareTo(f2)
if(x == 0){
return Character.compare(c1, c2);
}
return x;
您正在通過==
將兩個Integer
實例與if(map.get(c1) == map.get(c2))
語句進行比較。 它在頻率為 5 時起作用的原因是,在 -128…+127 范圍內對自動裝箱值進行強制緩存。 當頻率為 5000 時, Integer
對象的標識未指定,相同的對象可能具有不同的標識。
一種解決方法是使用 equals 代替。 另一種是停止手動實現Comparator
並使用工廠方法。 連同其他改進,您的代碼簡化為
Map<Character, Integer> map = new HashMap<>();
for(int i = 0; i < n; i++) {
map.merge(s.charAt(i), 1, Integer::sum);
}
Queue<Character> pq = new PriorityQueue<>(
Comparator.<Character>comparingInt(map::get).reversed()
.thenComparing(Comparator.naturalOrder())
);
map.forEach((key, freq) -> {
pq.offer(key);
System.out.println(key + " has freq " + freq);
});
while(!pq.isEmpty()) {
System.out.print(pq.poll() + " ");
}
您可以使用 .equals() 方法比較兩個對象。 它將返回 Boolean 值。 如果您想進行硬編碼比較,則為每個字母(總共 26 個變量)分配一個 integer 值並比較它們的 integer 值,您就會知道將哪個放在哪里。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.