排序字符的频率

时间:2014-01-24 05:19:57

标签: java sorting frequency frequency-distribution

我刚刚制作了一个算法来计算字符串中字符的频率。我感到困惑的是如何对频率进行排序,以便在顶部列出具有最大出现次数的字符,在底部列出最少的字符。

起初我尝试了另一个变量' fc' (对于频率计数器)与我原来的计数器变量' k'一致。然而,我陷入了如何对这个频率进行排序的思考过程中,我所做的fc var是没用的。

感谢您提供的任何帮助!

这是我的代码:

  import java.io.*;
public class Freq
{
    public static void main(String args[])throws IOException
    {
        //read input stream
        BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
        int ci,i,j,k,l,fc;l=0;
        String str,str1;
        char c,ch;
        System.out.println("Enter your String");
        str=in.readLine();
        i=str.length();
        //cycle through ASCII table chars and obtain chars typed
        for(c='A';c<='z';c++)
        {
            k=0;
            fc=0;           //fc keeps count like k
            for(j=0;j<i;j++)
            {
                ch=str.charAt(j);
                if(ch==c)
                    k++;
                    fc=k-1;     //was going to represent this counter for 'less than k'

            }
            if(k>0)
            System.out.println("The character "+c+" has occured for "+k+" times");
        }
    }
}

5 个答案:

答案 0 :(得分:3)

您需要先存储它们。您可以使用HashMap将它们全部存储起来,它还可以简化您的计算程序。然后在条目集上的Collections.sort。你需要制作一个可比较的&gt;比较排序的条目值。

编辑添加示例代码....

    BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
    System.out.println("Enter your String");
    String line = in.readLine();
    HashMap<Character,Integer> counts = new HashMap<>();
    for(char c : line.toCharArray()) {
        Integer count = counts.get(c);
        if (count == null) {
            count = 0;
        }
        counts.put(c, ++count);
    }
    List<Entry<Character,Integer>> list = new ArrayList<>(counts.entrySet());
    Collections.sort(list, new Comparator<Entry<Character,Integer>>() {
        @Override
        public int compare(Entry<Character, Integer> o1,
                Entry<Character, Integer> o2) {
            return o2.getValue() - o1.getValue();
        }
    });
    for(Entry<Character,Integer> entry : list) {
        System.out.println("The character "+entry.getKey() +" has occured for "+ entry.getValue()+" times");
    }

答案 1 :(得分:2)

You can follow these steps:

1) Create a class call CharCount having two fields : char and freq. Override equals to return true if characters are equal and override hashcode to return character's hashcode. Make it implement Comparable and override compare and return -1,0 or 1 based on values of freq of objects being compared
2) Have a Set of CharCount
3)Each time you find a character create an instance of this class with character and freq as 0.
4)Check if it exists in set and update feq accordingly
5) Sort set data yourself or call Collections.sort

答案 2 :(得分:2)

我会这样做:

int[] frequencyArray =  new int['z' -'A'];

String inputString = "ttttttttttttttttest";

for(int i = 0; i<inputString.length();i++)
{
    frequencyArray[inputString.charAt(i) -'A']++;
}

然后,您可以通过您选择的任何常用排序算法对此数组进行排序。

编辑使代码更具内存效率。

答案 3 :(得分:1)

创建一个函数计数,为您提供特定字符的计数和代表计数的排序,例如

if( count(str,str.charAt[j]) > count(str,str.charAt[j+1]) )
SWAP

最好在此之前将str转换为char数组,然后就像

count(chararr,charrarr[j]) 

答案 4 :(得分:0)

这个比Hashmap解决方案更快:

    public static void frequencySort(String s) {
        int[] f = new int[256];
        for (int c : s.toCharArray())
            f[c]++;
        List<CharStore> list = new ArrayList<>();
        for (int i = 0; i < f.length; i++) {
            if (f[i] != 0) list.add(new CharStore(i, f[i]));
        }
        Collections.sort(list);
        for (CharStore c : list) {
            System.out.println(((char)c.c) + " has occured " + c.count + " times";  
        }
    }

    static class CharStore implements Comparable<CharStore> {
        int c;
        int count;

        public CharStore(int c, int count) {
            this.c = c;
            this.count = count;
        }

        @Override
        public int compareTo(CharStore o) {
            return o.count - count;
        }
    }