簡體   English   中英

Java,如何在比較器中按字母順序對字符進行排序

[英]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'。
在此處輸入圖像描述

當每個字符的頻率為 5 時,順序正確。 在此處輸入圖像描述

我不明白為什么頻率為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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM