Java语言求解完美数代码分析

作者:ljtyzhr 时间:2023-01-28 10:17:58 

1、概念

首先我们理解一下,什么叫做完美数?

问题描述:若一个自然数,它所有的真因子(即除了自身以外的约数)的和恰好等于它本身,这种数叫做完全数。简称“完数”

例如,

6=1+2+3
28=1+2+4+7+14
496=1+2+4+8+16+31+62+124+248
8128=1+2+4+8+16+32+64+127+254+508+1016+2032+4064

按照完数的定义,其实用程序求解完数并不是太难,先求解出这个数的所有真因子,然后相加,判断是否等于它本身即可。但是,在这个数很小的时候,没有什么问题,一旦这个数字超过一定的数值,那么问题就来了,程序的执行效率就会变得低下。

我们优化程序的算法逻辑,往往会考虑一个问题,怎么高效的利用计算机的特性?在它所定义的算法中,有没有大量重复的无用功呢?沿着这样的思路去考虑这个问题,我们会很快得到另外的一种解决方案。

2、说明

2.1分析

在这里,我们会不会很容易就想到,之前我们提到过的分解因式?是的,在解决完美数的时候,我们会用到分解因式。一般来说,求解完美数会经过三个步骤:

1.求出一定数目的质数表

2.利用质数表求指定数的因式分解

3.利用因式分解求所有真因数和,并检查是否为完美数

2.2难点

初看之下,第一步和第二步是没什么问题的,我们在前面的两篇文章中已经探讨过了,不清楚的同学可以查看。

重点是在第三步,如何求真因数和?方法很简单,要先知道将所有真因数(有不清楚真因数概念的同学,去看看)和加上该数本身,会等于该数的两倍(有些同学不知道,现在应该也知道了吧?),例如:


2 * 28 = 1 + 2 + 4 + 7 + 14 + 28

事实上,这段等式可以转换为:(代码输入错误,我用截图好了)

Java语言求解完美数代码分析

发现没有?2和7都是因式分解得到的,那么,程序是不是有了简化的地方?

2.3结论

只要求出因式分解,就可以利用循环求得等式后面的值,将该值除以2就是真因数和了;等式后面第一眼看时可能想到使用等比级数公式来解,不过会使用到次方运算,可以在进行读取因式分解阵列时,同时计算出等式后面的值。

3、代码


import java.util.ArrayList;
// 求解完美数
public class PerfectNumber {
 // 传入一个值,求解至少多少个完美数
 public static int[] lessThan(int number) {
   int[] primes = Prime.findPrimes(number);

ArrayList list = new ArrayList();

for(int i = 1; i <= number; i++) {  
     int[] factors = factor(primes, i);  
     if(i == fsum(factors))  
       list.add(new Integer(i));
   }  

int[] p = new int[list.size()];
   Object[] objs = list.toArray();  
   for(int i = 0; i < p.length; i++) {
     p[i] = ((Integer) objs[i]).intValue();
   }

return p;
 }

// 分解因式
 private static int[] factor(int[] primes, int number) {  
   int[] frecord = new int[number];
   int k = 0;

for(int i = 0; Math.pow(primes[i], 2) <= number;) {  
     if(number % primes[i] == 0) {  
       frecord[k] = primes[i];  
       k++;  
       number /= primes[i];  
     }  
     else  
       i++;  
   }  

frecord[k] = number;  

return frecord;  
 }  

// 因式求和
 private static int fsum(int[] farr) {  
   int i, r, s, q;  

i = 0;  
   r = 1;  
   s = 1;  
   q = 1;  

while(i < farr.length) {  
     do {  
       r *= farr[i];  
       q += r;  
       i++;  
     } while(i < farr.length - 1 &&
         farr[i-1] == farr[i]);  
     s *= q;  
     r = 1;  
     q = 1;  
   }  

return s / 2;  
 }

public static void main(String[] args) {
   int[] pn = PerfectNumber.lessThan(1000);

for(int i = 0; i < pn.length; i++) {
     System.out.print(pn[i] + " ");
   }

System.out.println();
 }
}

来源:http://blog.csdn.net/ljtyzhr/article/details/38962569

标签:java,算法,数据结构,完美数
0
投稿

猜你喜欢

  • Java中对话框的弹出方法

    2022-04-24 14:35:52
  • java字符串的重要使用方法以及实例

    2023-11-13 23:11:51
  • 什么是递归?用Java写一个简单的递归程序

    2022-02-11 19:39:45
  • Java MongoDB数据库连接方法梳理

    2023-11-25 01:01:20
  • obix协议在java中的配置和使用详解

    2023-11-25 20:59:42
  • Java thread.isInterrupted() 返回值不确定结果分析解决

    2023-11-09 19:27:09
  • 关于Jsoup将相对路径转为绝对路径的方法

    2022-03-11 04:13:50
  • 详谈java 堆区、方法区和栈区

    2023-11-23 18:35:22
  • Java读文件修改默认换行符的实现

    2023-11-29 08:24:32
  • springboot vue组件开发实现接口断言功能

    2023-11-12 10:26:53
  • java使用正则表达校验手机号码示例(手机号码正则)

    2022-04-07 20:37:04
  • android使用PullToRefresh实现下拉刷新和上拉加载

    2023-08-06 11:06:58
  • Java中的内部类使用详情

    2022-07-24 05:09:38
  • 关于Mybatis-Plus Update更新策略问题

    2022-04-14 19:29:24
  • Spring Boot Admin实践详解

    2023-08-25 06:57:53
  • Java代码实现酒店管理系统

    2023-08-13 13:09:23
  • javaweb学习总结——使用JDBC处理MySQL大数据

    2022-10-19 22:45:32
  • SpringBoot定制三种错误页面及错误数据方法示例

    2022-03-10 01:15:55
  • C语言 OutputDebugString与格式化输出函数OutputDebugPrintf案例详解

    2023-11-02 16:21:47
  • Java读取TXT文件内容的方法

    2023-11-23 22:33:41
  • asp之家 软件编程 m.aspxhome.com