[英]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.