具有流的正整数的素因子分解

4ca*_*tle 6 java prime-factoring java-8 java-stream

我目前正在尝试将Java 8的Stream API合并到我的日常Java工具箱中.我正在尝试使用Streams来查找正整数的素因子,然后将每个因子存储在数组(或ArrayList)中,并将它们的多重性存储在并行数组中.或者,我正在尝试创建一个说... FactorWithMultiplicity对象的流,或者甚至Map用因子作为键,多重性作为值.如果因子按升序排序,如果它甚至可以处理非常大的数字(例如,我敢说,那么Long.MAX_VALUE)会很好.

目前,我的代码看起来像这样,但是,由于我是Streams的初学者,我确信有更快或更适合的方式来完成此任务.请使用Streams创建您的解决方案,但如果您知道某些非Stream解决方案更快,请随时向我指出该代码.

int num = getPositiveInt();
ArrayList<Integer> factors = new ArrayList<>();
ArrayList<Integer> multiplicities = new ArrayList<>();
boolean isPrime = IntStream.rangeClosed(2, num / 2)
    .reduce(num, (int temp, int factor) -> {
        int count = 0;
        while (temp % factor == 0) {
            temp /= factor;
            count++;
        }
        if (count > 0) {
            factors.add(factor);
            multiplicities.add(count);
        }
        return temp;
    }) > 1;
Run Code Online (Sandbox Code Playgroud)

Mis*_*sha 5

如果您特别想要基于流的解决方案,则可以使用一种递归分解数字的方法:

IntStream factors(int num) {
    return IntStream.range(2, num)
        .filter(x -> num % x == 0)
        .mapToObj(x -> IntStream.concat(IntStream.of(x), factors(num / x)))
        .findFirst()
        .orElse(IntStream.of(num));
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用以下代码创建两个列表:

Map<Integer, Integer> f2m = factors(2, num).boxed()
        .collect(toMap(f -> f, f -> 1, Integer::sum));  // or groupingBy with summingInt(f->1), whichever you prefer

List<Integer> factors = new ArrayList<>(f2m.keySet());
List<Integer> multiplicities = factors.stream().map(f2m::get).collect(toList());
Run Code Online (Sandbox Code Playgroud)

如果您想从中获得更多性能,可以将上次找到的因素传递给factorsmethod,并使用代替2

如果您想考虑长期因素,请使用以下版本,该版本在性能上有一些改进:

static LongStream factors(long lastFactor, long num) {
    return LongStream.rangeClosed(lastFactor, (long) Math.sqrt(num))
            .filter(x -> num % x == 0)
            .mapToObj(x -> LongStream.concat(LongStream.of(x), factors(x, num / x)))
            .findFirst()
            .orElse(LongStream.of(num));
}
Run Code Online (Sandbox Code Playgroud)

如果希望结果按顺序排列,则可以使用

SortedMap<Long, Integer> f2m = factors(2, num).boxed()
         .collect(toMap(f -> f, f -> 1, Integer::sum, TreeMap::new));
Run Code Online (Sandbox Code Playgroud)

或者,保持Map原样并使用

List<Long> factors = f2m.keySet().stream().sorted().collect(toList());
Run Code Online (Sandbox Code Playgroud)