【问题标题】:Sorting this output numerically?对这个输出进行数字排序?
【发布时间】:2017-10-23 05:24:36
【问题描述】:

我的程序将一个字符串作为用户的输入。此方法特别返回字符串中的每个唯一字符及其重复次数。输出按 ASCII 顺序排序(最低 ASCII 值在前)。有没有办法根据每个字符出现的次数对这个列表进行排序(即最常见的字符在前,最不常见的字符在后)?此外,如果两个字符出现的次数相同,有没有办法让 ASCII 表中的第一个字符排在最前面?这是我正在尝试处理的代码。

public static void alphabeticalSort(String input)
{
    int[] ascii = new int[256];

    for (int i = 0; i < input.length(); i++) {
        char current = input.charAt(i);
        ascii[(int)current]++;
    }

    System.out.println(IntStream.range(0, ascii.length).filter(x -> ascii[x] > 0).mapToObj(x -> String.format("%s: freq %s", (char) x, ascii[x])).collect(Collectors.joining("\n")));
}

【问题讨论】:

  • 你的第一个 IntStream 没有任何作用。
  • 你所要求的毫无意义。如果您对数组进行排序,您的角色将不复存在。你需要使用地图或其他东西。
  • FWIW,对数组进行排序非常简单:Arrays.sort(ascii);
  • 这些角色将不复存在是什么意思?
  • 如果你通过索引来识别字符,你不能打乱这些值并且仍然保留与它们字符的关系。试试看,你很快就会明白我的意思。

标签: java string sorting


【解决方案1】:

您不需要char[] - 只需流式传输输入字符串,使用分组收集器收集它,该收集器计算出现次数并直接对结果映射进行排序:

input.chars()
     .mapToObj(c -> Character.valueOf((char) c))
     .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
     .entrySet()
     .stream()
     .sorted(Map.Entry.<Character, Long> comparingByValue()                    
                      .reversed()
                      .thenComparing(Map.Entry.comparingByKey()))
     .map(e -> String.format("%s: freq %d", e.getKey(), e.getValue()))
     .forEach(System.out::println); 

【讨论】:

  • mapToObj(c -&gt; (char)c)
  • @shmosel 是的,那行得通。我更喜欢 Character.valueOf 的明确性,但我想这比什么都重要。
  • 我认为mapToObj 已经很明确了,但我猜对他们自己来说。
  • 这适用于不合并字符 (Character.GetType(c) != Character.NON_SPACING_MARK) 的字符串中 BMP 范围 (!Character.isSurrogate(c)) 中的字符。所以,没有?也没有O̝。
【解决方案2】:

我对您的问题有一些不同的方法,但它可能会对您有所帮助。您可以创建自己的对来计算频率,然后使用比较使用频率对其进行排序,如果频率匹配,然后使用 char。 这里是统计频率。

    public class Pair
    {
        private char letter;
        private int freq;
        public Pair(char letter, int freq)
        {
            this.letter = letter;
            this.freq= freq;
        }
        public char getLetter(){
            return letter;
        }
        public int getFreq(){
            return freq;
        }
    }
    public static int countFreq(String str, char c)
    {
        int count = 0;
        for(int i = 0; i < str.length(); i++)
        {
            if(str.charAt(i) == c) 
                count++;
        }
        return count;
    }

调用此方法创建一对字母和频率

    public static List<Pair> createPair(String str)
    {
        String s = str;
        List<Pair> list = new ArrayList<Pair>();
        while(s.length() != 0)
        {
            list.add(new Pair(s.charAt(0), countFreq(s,s.charAt(0))));
            s.replaceAll(s.charAt(0),"");
        }
         return list;
    }

然后您可以使用稳定的字母排序,然后使用频率。 代码可能有错误,因为我没有测试它,因为它是为了给你我的一般想法。
您也可以参考here 了解更多想法。
对于排序,这里有各种稳定排序的选项。在 Java 中,Collections.sort 使用稳定的排序,所以你不应该有问题。除此之外,您可以使用比较功能来获得帮助。希望它能给你一个普遍的看法

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-07
    • 1970-01-01
    • 2016-10-11
    • 2019-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多