Java Stream来写算法11——分解质因数

16 篇文章 0 订阅
16 篇文章 0 订阅

总目录

  • 之前的文章写过如何求解出指定数字的全部约数,这篇文章更进一步,求解出全部的质因数,比如,求36的质因数:2、2、3、3
  • 与元素周期表类似,世间万物都是由周期表中的元素所组成,而所有的数字,也都是这些质因数,逐个累加而成
  • 求解质因数的过程,需要知道原数字与其中某个质因数相除的商,所以不适合用Stream流式方法,所以核心逻辑代码,还是使用的普通的for、while语句来完成的

代码

public class Factor {
    /* 求解全部因数,不要求每一个因数都是质数 */
    IntConsumer allFactors = value -> {
        int root = Double.valueOf(Math.sqrt(value)).intValue();
        List<Integer> list = new ArrayList<>();
        IntStream.iterate(1, v -> v + 1).limit(root)
                .filter(v -> value % v == 0).forEach(v -> {
                    list.add(v);
                    int v1 = value / v;
                    if (v1 != v) list.add(v1);
                });
        Collections.sort(list);
        System.out.println(list);
    };
    /* 求解全部质因数 */
    void allPrimeFactors(final int value) {
        List<Integer> list = new ArrayList<>();
        int root = Double.valueOf(Math.sqrt(value)).intValue();
        int dividend = value;
        for (int i = 2; i <= root; i++) {
            while (dividend % i == 0 ) {
                // 发现一个质因数,一直把该质因数有多少个全求出来
                // 例如2是24的质因数,while循环第一遍,会把2先添加进来
                // 然后求24/2=12,发现2还是12的质因数,再添加一个2,再计算12/2=6
                // ……
                // 这样一直求到6/2=3,而2不再是3的质因数为止
                if (isPrime(i))
                	list.add(i);
                dividend = dividend / i;
                if (isPrime(dividend) && divident > root) {
                    // 如果发现与i成对的另一个因数也是质数
                    // 说明这个数只有两个质因数,而不会再有其他因数
                    // 用break跳出while循环,将i设为一个大数,再跳出for循环
                    // 从而彻底跳出全部循环
                    list.add(dividend);
                    i = root + 1;
                    break;
                }
            }
        }
        if (list.size() == 0)
            list.add(value);
        Collections.sort(list);
        System.out.println(list);
    }

    boolean isPrime(int v) {
        if (v == 2 || v == 3 || v == 5) return true;
        if (v % 2 == 0) return false;
        int sqrtValue = Double.valueOf(Math.sqrt(v)).intValue();
        return IntStream.iterate(3, oddValue -> oddValue + 2).limit(sqrtValue).parallel()
                .filter(v1 -> v1 <= sqrtValue).noneMatch(v1 -> v % v1 == 0);
    }
}
  • 这里面判断一个数是不是质数,用到了Stream流的写法,这样总可以不算是挂羊头卖狗肉了
  • 此文章代码的解释,在总目录中标示的其文章中也有详细解释,这里就不赘述了

测试代码

class FactorTest {
    @Test
    void test() {
        Factor factor = new Factor();
        factor.allFactors.accept(36);
        factor.allPrimeFactors(97);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值