总目录
求给定数字 n n n的约数,算法很简单,需要从 1 1 1开始一直找到 n n n,如果能整除就符合。
分析
- 但是上面的遍历算法,需要查找数据太多,所以需要优化,减少遍历数据的量,所以就有了如下优化。
- 因为约数是成对出现的,所以简化查找范围可以减少到从 1 1 1查找到 n \sqrt{n} n,这样遍历范围会大大缩小,但这个范围只会取到一半的约数。
- 例如要求12的约数,从1开始,到 12 \sqrt{12} 12只取整数为3,计算得到的约数为1、2、3,但与这些约数对应的约数12、6、4取不到,但可以通过12/1、12/2、12/3来取得,所以还是首先把1、2、3求解出来,然后再用除法把4、6、12求解出来。
代码
private void getFactors(int value) {
List<Integer> list = new ArrayList<>();// 保存全部约数的列表
int[] array = IntStream.iterate(1, v -> v + 1)// 生成数列1,2,3,4……
// 控制数列数据量,只到根号n。这里没有使用强制类型转换来取整数,而是使用Double中的方法来取整数值
.limit(Double.valueOf(Math.sqrt(value)).intValue())
.filter(v -> value % v == 0).// 将可以整除的数筛选出来
.forEach(v -> {
list.add(v);
if (value / v != v) {// 这个判断是为了把重复的约数去掉一个,比如36其中一对约数是两个6,要去掉一个
list.add(value / v);
}
}// forEach是把找到的1、2,3加入到list列表中,同时把12/1、12/2、12/3的值也加入到列表中
);
Collections.sort(list);// 将列表中数据排序
System.out.println(list);
}
这部分代码是彻底告别了for、while语句