1

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

起初我尝试让另一个变量“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");
        }
    }
}
4

5 回答 5

3

您需要先将它们全部存储起来。您可以使用 HashMap 来存储它们,它还将简化您的计数程序。然后 Collections.sort 对条目集进行排序。您将需要创建一个 Comparable> 来比较条目值以进行排序。

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

    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");
    }
于 2014-01-24T05:28:54.563 回答
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
于 2014-01-24T05:32:51.840 回答
2

我会这样做:

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

String inputString = "ttttttttttttttttest";

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

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

编辑使代码更节省内存。

于 2014-01-24T05:34:00.420 回答
1

制作一个函数计数,为您提供特定字符的计数并代表计数进行排序,例如

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

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

count(chararr,charrarr[j]) 
于 2014-01-24T05:28:06.850 回答
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;
        }
    }
于 2016-11-16T04:36:41.080 回答