字符串排序降序使用java基于重复字符的次数

时间:2014-11-29 01:06:38

标签: java string

这里我有两个字符串打印每个字符发生了多少次但我希望该结果按降序排列。

 public static void main(String[] args) {
    TreeMap tm = new TreeMap();
    String s = "ajklfajdlkfajsdklfjalljaklsdfjaklsdjf";
    int[] counts = new int[128];
    for (int i = 0; i < s.length(); i++) {
        char ch = s.charAt(i);
        if (ch < 128) {
            counts[ch]++;
        } else {
            System.out.println("out of range");
        }
    }
    for (char c = 0; c < 128; c++) {
        if (counts[c] != 0) {
            tm.put(counts[c], c);
  //                System.out.println(c + " occured " + counts[c] + "times");
        }
    }
    for(int i=0;i<tm.size();i++){
        System.out.println(tm.get(i));
    }
   }

此代码输出为:null,null,null,s,d但我需要输出为:j l a f k d s。请指导我。

3 个答案:

答案 0 :(得分:0)

您的方法是正确的,但有一些小的改动。

首先,您应该明确说明泛型集合中的类型: TreeMap&lt; Integer,Set&lt; Characters&gt;&gt;

您希望将计数映射到一组字符,因为可能有两个或多个字符出现的次数相同。否则插入地图将覆盖先前的计数 - &gt; char mapping。

其次,你想将你的角色追加到一个计数的末尾 - &gt; char设置,如果它已经存在于地图中。原因如上所述。

第三,整数的TreeMap按升序排序,因此请参阅javadoc以了解如何获取TreeMap的降序视图。 Java TreeMap

最后,要遍历地图,您可以遍历entrySet()或values()。再次,检查javadocs是你最好的朋友。

public static void main(String[] args) {
    TreeMap<Integer, Set<Character>> tm = new TreeMap<Integer, Set<Character>>();
    String s = "ajklfajdlkfajsdklfjalljaklsdfjaklsdjf";
    int[] counts = new int[128];
    for (int i = 0; i < s.length(); i++) {
        char ch = s.charAt(i);
        if (ch < 128) {
            counts[ch]++;
        } else {
            System.out.println("out of range");
        }
    }
    for (char c = 0; c < 128; c++) {
        if (counts[c] != 0) {
            if (tm.contains(counts[c])) {
                // Collision, there's already a character that appeared
                // this number of times
                tm.get(counts[c]).add(c);
            } else {
                Set<Character> charSet = new HashSet<Character>();
                charSet.add(c);
                tm.put(counts[c], charSet);
            }
        }
    }

    NavigableMap<Integer, Set<Character>> descendingMap = tm.descendingMap();
    for (Map.Entry<Integer, Set<Character>> entry : descendingMap.entrySet()) {
        //int count = entry.getKey();
        Set<Character> chars = entry.getValue();
        for (char c : chars) {
                System.out.println(c);
            }
        }
    }
}

更新为使用Set而不是list来提高效率。

答案 1 :(得分:0)

您的方法存在一些问题:

  1. 您有TreeMap从char计数映射到char。如果多个字符以相同的计数出现,那么除了1个字符外,你将松开所有字符。

  2. 您使用get的{​​{1}}方法,这意味着您获得了TreeMap次{$ 1}}次的字符,而不是i的值地图中的第 - 个条目。

  3. 这是您的另一种选择:

    • 创建一个i类,其中包含char和count的字段。
    • 使用Container代替TreeSet

    代码:

    TreeMap

答案 2 :(得分:0)

我的回答可能与其他人一样,但我试图遵循原始代码的精神,他们只是更快地编写它。

package uk.co.puce4.charactercount;

import java.util.Iterator;
import java.util.TreeMap;
import java.util.TreeSet;


public class CharacterCount {
public static void main(String[] args)
{ 
    TreeMap<Character,Integer> tm = new TreeMap<Character,Integer>();

    String s = "ajklfajdlkfajsdklfjalljaklsdfjaklsdjf"; 

    for (int i = 0; i < s.length(); i++) { 
        char ch = s.charAt(i); 
        int count = 1;
        if(tm.containsKey(ch)){
            count=tm.get(ch) + 1;
        }
        tm.put(ch, count);
    }

    TreeSet<CharItem> ts = new TreeSet<CharItem>(); 
    Iterator<Character> it = tm.descendingKeySet().iterator();

    while (it.hasNext()){
        char ch = (char) it.next();
        int count = tm.get(ch);
        CharItem ci= new CharItem(ch, count);
        ts.add(ci);
        }
        Iterator<CharItem> it2 = ts.iterator(); 
        while(it2.hasNext()){
            CharItem ci=it2.next();
            System.out.println(ci.getCh() + " occured " + ci.getCount() + " times"); 
        }
    }
}

class CharItem implements Comparable<CharItem>{
    private int count;
    private char ch;
    public CharItem(char c, int i){
        count = i;
        ch = c;
    }
    public char getCh() {
        return this.ch;
                }
    public int getCount() {
        return this.count;
        }

    @Override
    public int compareTo(CharItem b) {
        return b.count - this.count ;
    }
}