簡體   English   中英

如何排序ArrayList <String> 包含整數?

[英]How do I sort an ArrayList<String> that contains integers?

我制作了一個單詞計數器二進制搜索樹,當輸入一個以上單詞時,它會增加一個單詞的計數。 單詞和單詞計數都保存在樹中。 我試圖先打印出計數最高的單詞,然后按降序排列。

為了執行此操作,我將BST轉換為ArrayList,但現在似乎無法弄清楚如何通過減少計數順序對列表進行排序。 這是我到目前為止的內容:

public ArrayList<String> toArray() {
  ArrayList<String> result = new ArrayList<String>();
  toArrayHelp(root, result);
  Collections.sort(result);
  return result;
}

private void toArrayHelp(Node<String, Integer> node, ArrayList<String> result) {
  if (node == null) {
      return;
  }
  toArrayHelp(node.left, result); 
  result.add("count: " + String.valueOf(node.count) + "/t word: " + node.data); 
  toArrayHelp(node.right, result); 
}

我已經嘗試過Collections.sort(),但是它不是按字符串而是僅按單詞排序。

  • 遍歷樹,從所有元素生成List<Node<String, Integer>>
  • List排序,按節點的int部分排序
  • 創建一個僅保留字符串的列表,順序相同

您構建輸出字符串的時間太早:您需要首先使用count作為鍵對列表進行排序,然后打印結果。 您可以制作一個包含結果的簡單包裝器:

public class WordCount implements Comparable<WordCount>{
   private String word;
   private Integer count;

   //constructors, getters, setters etc..

   @Override
   public int compareTo(WordCount other) {
       return Integer.compare(this.count, other.count);
   }

}

並在遍歷樹時構造一個List<WordCount> list 完成后,您只需要按Collections.sort(list)對列表進行排序並打印結果即可。

1.對於DESC訂單,請使用Collections.sort(result, Collections.reverseOrder()); 因為默認的排序順序是ASC。

2.確保count的字符串表示長度相同。 否則,字典順序假定11 <2:

List<String> list = Arrays.asList("11", "1", "2");
Collections.sort(list, Collections.reverseOrder());
System.out.println(list); // output: [2, 11, 1]

但是,如果數字具有相同的長度,則可以正常工作:

List<String> list = Arrays.asList("11", "01", "02");
Collections.sort(list, Collections.reverseOrder());
System.out.println(list); // output: [11, 02, 01]

如何添加前導零,可以在這里https://stackoverflow.com/a/275715/4671833找到。 應該是這樣的結果result.add("count: " + String.format("%02d", String.valueOf(node.count)) + "/t word: " + node.data);

兩點要點:讓名稱選擇和格式成為您的朋友! 您需要養成選擇簡單且富有表現力的變量名的習慣,並保持代碼的格式整齊。

讓我們從明確的步驟開始:

(1)有單詞數據源,表示為節點樹。 為了避免過多的細節,讓我們設置節點類型的重要細節,並使用getter使節點樹可用。

值得一提的重要細節是,節點打算保留在具有不同鍵值的已排序二叉樹中,為此,任何左節點的值均嚴格小於該節點的值,而任何右節點的值均小於該節點的值。節點嚴格大於節點的值。 這具有重要的結果,即節點的左子樹的值都嚴格小於該節點的值,並且右子樹的值同樣均嚴格大於該節點的值。

public class Node<K, V> {
  public K key;
  public V value;

  public Node<K, V> left;
  public Node<K, V> right;

  public Node(K key, V value) {
    this.key = key;
    this.value = value;
  }
}

public Node<String, Integer> getRootNode() {
    // Undetailed ...
}

(2)需要三個主要操作:將樹的節點收集到列表中的操作,對該列表進行排序的操作以及顯示排序后的列表的操作:

public List<Node<String, Integer>> flatten(Node<String, Integer> rootNode) {
    // Undetailed ...
}

public void sort(List<Node<String, Integer>> nodes) {
    // Undetailed ...
}

public void print(List<Node<String, Integer>> nodes) {
    // Undetailed ...
}

(3)例如,如下所示:

public void tester() {
  Node<String, Integer> rootNode = getRootNode();
  List<Node<String, Integer>> flatNodes = flatten(rootNode);
  sort(flatNodes);
  print(flatNodes)l
}

(4)剩下的就是詳細介紹幾種方法。 我們從“展平”開始。 這將被實現為遞歸操作。 並且,由於為平面列表傳遞存儲更簡單,因此該方法將分為兩部分,一部分分配存儲,另一部分進行遞歸處理。 這種傳遞存儲集合的技術是此類處理的典型方法。

'flatten'利用節點相對於節點的左節點和節點的右節點的排序屬性:'flatten'將左子樹的所有值添加到平面節點列表中,然后是節點,然后是節點右子樹的所有值。

public List<Node<String, Integer>> flatten(Node<String, Integer> rootNode) {
    List<Node<String, Integer>> flatNodes = new ArrayList<Node<String, Integer>>();
    flatten(rootNode, flatNodes);
    return flatNodes;
}

public void flatten(Node<String, Integer> node, List<Node<String, Integer>> flatNodes) {
   if ( node == null ) {
       return;
   }
   flatten(node.left, flatNodes);
   flatNodes.add(node);
   flatten(node.right, flatNodes);
}

(5)出於清晰的考慮,可以通過移動null檢查來使之更加有效。 對於完全平衡的樹,這將避免約2/3的遞歸調用,這是相當不錯的減少。 這僅在節點數很高時才重要。 無論如何,一個好的編譯器很可能會以這種方式轉換代碼。

public List<Node<String, Integer>> flatten(Node<String, Integer> rootNode) {
    List<Node<String, Integer>> flatNodes = new ArrayList<Node<String, Integer>>();
    if ( rootNode != null ) {
        flatten(rootNode, flatNodes);
    }
    return flatNodes;
}

public void flatten(Node<String, Integer> node, List<Node<String, Integer>> flatNodes) {
    Node<String, Integer> leftNode = node.left;
    if ( leftNode != null ) {
        flatten(leftNode, flatNodes);
    }

    flatNodes.add(node);

    Node<String, Integer> rightNode = node.right;
    if ( rightNode != null ) {
        flatten(rightNode, flatNodes);
    }
}

(6)接下來的一點是對平面節點列表進行排序。 提出了兩種實現,一種使用lambda的更現代的實現,以及一種使用顯式比較器的較舊樣式的實現。 編寫比較以生成從最小到最大排序的列表。 要顛倒排序順序,請交換比較順序。

public void sort(List<Node<String, Integer>> nodes) {
    Collections.sort(
        nodes,
        ((Node<String, Integer> n1, Node<String, Integer> n2) -> Integer.compare(n1.value, n2.value)) );
}

public static final Comparator<Node<String, Integer>> NODE_COMPARATOR = 
    new Comparator<Node<String, Integer>>() {
        public int compare(Node<String, Integer> n1, Node<String, Integer> n2) {
            return Integer.compare(n1.value, n2.value);
        }
    };

public void sort(List<Node<String, Integer>> nodes) {
    Collections.sort(nodes, NODE_COMPARATOR);
}

(7)作為結果,打印結果排序列表。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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