如何创建一个与2到100的每个数字相对应的列表,该列表将包含数组倍数的数字?

时间:2019-05-28 06:25:34

标签: java logic

最近我遇到了这个问题,无法找到最佳解决方案。

假设我们有一个任意范围的数字数组,例如9,-3,0,4,11,2,-8,..... 我们需要打印2到100之间的数字,并且与每个数字相对应,我们需要从数组中打印数字列表,以使数组中的数字可被其整除。 例: 以现有阵列为例, 2 -> 4,2,-8,... 3 -> -3,9,... 4 -> 4,-8,... 最多可以达到100个。

我尝试通过将数组的每个数字除以2到100来确定解决方案,然后创建与每个数字相对应的列表。但这在我看来并不是最佳解决方案。

我什至尝试对数字进行分组,例如被8整除的数字将被2和4整除,因此我们无需再次将其除。这样可以减少一些操作和复杂性,但又需要创建此类组。

请通过减少将每个数字除以2到100的需要,任何人都可以帮助找到最佳解决方案。

2 个答案:

答案 0 :(得分:2)

要解决给定的问题,我将选择以下两种方法之一:

版本1

结合方法map.computeIfAbsent的两个简单的嵌套循环

int[] myArray = {3,5,1,-7,6,34,88,2,-8,9,10,4,33};
Map<Integer,List<Integer>> version1 = new HashMap<>();
for(int i = 2; i< 100; i++){
    for(int x : myArray){
        if(x%i==0)
           version1.computeIfAbsent(i, k -> new ArrayList<>()).add(x);
    }            
}
System.out.println(version1);

版本2

仅具有流操作的解决方案

    Map<Integer,List<Integer>> version2 = Arrays.stream(myArray).distinct().boxed()
            .flatMap(p -> IntStream.range(2, 100).filter(i -> p%i ==0).boxed()
                    .map(l->new AbstractMap.SimpleEntry<>(l,p)))
            .collect(Collectors.groupingBy(Map.Entry::getKey,
                    Collectors.mapping(Map.Entry::getValue, Collectors.toList())));

    System.out.println(version2);

肯定有更优雅的解决方案,或者说就复杂性而言最佳的解决方案。但是我认为这里的方法简短易懂。

答案 1 :(得分:1)

如果您保留每个子列表的位置,则可以使用以前的结果来限制列表的长度:

    List<List<Integer>> lists = new ArrayList<>();
    lists.add(list); // at 0: never used
    lists.add(list);
    for (int i = 2; i <= 100; ++i) {
        for (int j = i/2; j > 0; --j) {
            if (i%j == 0) {
                lists.add(extractMultiples(lists.get(j), i));
                break;
            }
        }
    }
    for (int i = 2; i <= 100; ++i) {
        System.out.println(i + ": " + lists.get(i));
    }

使用方法extractMultiples

public static List<Integer> extractMultiples(List<Integer> list, int n) {
    List<Integer> result = new ArrayList<>();
    for (int x: list) {
        if (x%n == 0) {
            result.add(x);
        }
    }
    return result;
}