繁体   English   中英

如何按数字的位数对列表中的数字进行分组

[英]How can I group numbers in a list by their number of digits

所以我的问题是我不知道如何按长度对Map<<Integer, List<Integer>>进行排序。

例如,您有列表 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 153, 370, 371, 407],

答案应该是 {1=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 3=[153, 370, 371, 407]}

我为阿姆斯壮数(armstrongs)写了代码

    List<Integer> lance = armstrongs(500); 
    System.out.println(lance); 
    // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 153, 370, 371, 407]

    Map<Integer, List<Integer>> grouped = groupByLength(lance);
    System.out.println(grouped);
    // {1=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 3=[153, 370, 371, 407]}

我的问题是,如何按长度和长度编号对列表进行排序?

我唯一拥有的是

public static Map<Integer, List<Integer>> groupByLength(List<Integer> x){
    return null;
}

Java 的Stream操作非常适合此类问题。 特别是,方法groupingBy正是您所需要的:它创建一个对象,该对象将列表支持的流中的所有元素收集到一个映射中,该映射将分类器(在您的情况下为数字)映射到按以下分组的元素列表那个分类器。

public static Map<Integer, List<Integer>> groupByLength(List<Integer> x) {
    return x.stream()
            .collect(Collectors.groupingBy(n -> Integer.toString(n).length()));
}

假设您最多只有三位数,您可以尝试一些这样的代码(未经测试);

public static Map<Integer, List<Integer>> groupByLength(List<Integer> x){
    List<Integer> group1 = new LinkedList<>();
    List<Integer> group2 = new LinkedList<>();
    List<Integer> group3 = new LinkedList<>();
    Map <Integer,List<Integer>> map = new HashMap<>();

    for(int i = 0; i < x.size(); i++){
        int length = String.valueOf(x.get(i)).length();
        if(length = 1){
            group1.add(x.get(i));
        }else if(length = 2){
            group2.add(x.get(i));
        }else{
            group3.add(x.get(i));
        }
    }

    if(group1.size()>0)
        map.put(1,group1);
    if(group2.size()>0)
        map.put(2,group2);
    if(group3.size()>0)
        map.put(3,group3);
    return map;
}

由于您正在计算阿姆斯壮数,这是重要的信息,因为您已经有了length值。

streams的优点之一是它们消除了中间容器并允许处理呈现的值。 在您的情况下,您计算了阿姆斯特朗数,将它们放入列表中,然后放入地图中。

根据您的要求,也许更好的方法是在计算它们时将它们放入地图中。 如果需要,您也可以同时将它们收集到列表中。

要计算阿姆斯特朗数,您已经有了长度len因为您需要将单个数字提高到那个幂。 所以你应该用它来对你的数字进行分类。

分配你的HashMap

 Map<Integer, List<Integer<> arms = new HashMap<>();

然后,在计算阿姆斯壮数时,请执行以下操作。

`len` is length of number
`arm_number` is your latest Armstrong number

    map.compute(len,
                  (k, v) -> v == null ? new ArrayList<>()
                        : v).add(arm_number);

上面,使用键len来查看列表是否存在。 它要么返回该列表,要么创建一个新列表。 .add然后将该号码添加到该列表中。

通过即时执行,您可以节省时间并仍然获得所需的结果。

这是一个完美的例子,其中 Streams 非常适合此类问题。 使用 Streams,您可以通过几行代码完成此操作:

public static Map<Integer, List<Integer>> groupByLength(List<Integer> x){
    return x.stream()
            .collect(Collectors.groupingBy(
                (Integer i) -> Integer.toString(i).length(), // Grouping by length
                TreeMap::new, // Lengths are sorted
                Collectors.toList())); // Each group is List<Integer>
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM