- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试编写一个Java方法来检查数字是否为完美数字。
理想数是一个等于其所有除数(不包括其自身)之和的数字。
例如,6是一个完美的数字,因为1+2+3=6
。然后,我必须编写一个Java程序以使用该方法显示前5个完美数字。
除了这个问题,我没有任何问题,因为它永远需要第五个完美数字33550336
。
我知道这是因为isPerfectNumber()
方法中的for循环。但是,我对编码非常陌生,我不知道如何提出更好的代码。
public class Labreport2q1 {
public static void main(String[] args) {
//Display the 5 first perfect numbers
int counter = 0,
i = 0;
while (counter != 5) {
i++;
isPerfectNumber(i);
if (isPerfectNumber(i)) {
counter++;
System.out.println(i + " ");
}
}
}
public static boolean isPerfectNumber(int a) {
int divisor = 0;
int sum = 0;
for (int i = 1; i < a; i++) {
if (a % i == 0) {
divisor = i;
sum += divisor;
}
}
return sum == a;
}
}
This is the output that is missing the 5th perfect number
最佳答案
让我们检查一个完美数字的属性。 This Math Overflow question告诉我们两个非常有趣的事情:
int
是32位。在这里,我们看到了功率和位位置之间的直接关系。多亏了这一点,而不是对
isPerfectNumber
进行数百万次的调用,我们将少于32个来找到第5个完美的数字。
int count = 0;
for (int k = 1; count < 5; k++) {
// Compute candidates based on the formula.
int candidate = (1L << (k - 1)) * ((1L << k) - 1);
// Only test candidates, not all the numbers.
if (isPerfectNumber(candidate)) {
count++;
System.out.println(candidate);
}
}
这是我们的重大胜利。没有其他优化可以胜过这一点:为什么要测试3,300万个数字,而您却可以测试少于100个数字?
isPerfectNumber(int)
。
d
除以
n
,则
n/d
也除以
n
。您可以一次添加两个除数。但是美丽之处在于您可以在
sqrt(n)
处停止,因为
sqrt(n)*sqrt(n) = n
在数学上是可以的。因此,仅测试
n
除数,而不是测试
sqrt(n)
除数。
1
和
sqrt(n)
:
1
是一个特例,因为如果将n
除以1
,则会得到n
,但无需添加n
即可检查n
是否为理想数字。您只添加1
。因此,我们可能会从1
开始求和,以避免出现过多的if
。 sqrt(n)
是一个极端的情况,因为我们必须检查sqrt(n)
是否为整数,并且它很乏味。但是我提到的数学溢出问题说,没有完美的数字是一个完美的平方,因此可以简化我们的循环条件。 sum
大于
n
,我们可以停止。适当的除数之和大于
n
表示
n
丰富,因此不是完美的。这是一个很小的进步,但实际上很多候选人都很丰富。因此,如果保留它,您可能会节省几个周期。
static boolean isPerfectNumber(int n) {
// 1 would pass the rest because it has everything of a perfect number
// except that its only divisor is itself, and we need at least 2 divisors.
if (n < 2) return false;
// divisor 1 is such a corner case that it's very easy to handle:
// just start the sum with it already.
int sum = 1;
// We can stop the divisors at sqrt(n), but this is floored.
int sqrt = (int)Math.sqrt(n);
// A perfect number is never a square.
// It's useful to make this test here if we take the function
// without the context of the sparse candidates, because we
// might get some weird results if this method is simply
// copy-pasted and tested on all numbers.
// This condition can be removed in the final program because we
// know that no numbers of the form indicated above is a square.
if (sqrt * sqrt == n) {
return false;
}
// Since sqrt is floored, some values can still be interesting.
// For instance if you take n = 6, floor(sqrt(n)) = 2, and
// 2 is a proper divisor of 6, so we must keep it, we do it by
// using the <= operator.
// Also, sqrt * sqrt != n, so we can safely loop to sqrt
for (int div = 2; div <= sqrt; div++) {
if (n % div == 0) {
// Add both the divisor and n / divisor.
sum += div + n / div;
// Early fail if the number is abundant.
if (sum > n) return false;
}
}
return n == sum;
}
这些优化使得您甚至可以在一秒钟内找到第七个完美数字,只要您将代码改写为
long
而不是
int
即可。而且您仍然可以在30秒内找到第8名。
public class Main {
public static void main(String[] args) {
int count = 0;
for (int k = 1; count < 8; k++) {
long candidate = (1L << (k - 1)) * ((1L << k) - 1);
if (isPerfectNumber(candidate)) {
count++;
System.out.println(candidate);
}
}
}
static boolean isPerfectNumber(long n) {
if (n < 2) return false;
long sum = 1;
long sqrt = (long)Math.sqrt(n);
for (long div = 2; div <= sqrt; div++) {
if (n % div == 0) {
sum += div + n / div;
if (sum > n) return false;
}
}
return n == sum;
}
}
上面程序的结果是前8个完美数字的列表:
6
28
496
8128
33550336
8589869056
137438691328
2305843008139952128
您可以找到进一步的优化,特别是在搜索中是否检查2k-1是否为
Eran says in their answer为素数,但是鉴于
long
的候选对象少于100个,我发现潜在地增加几毫秒的有用性并不大因为在此程序中,计算素数也可能很昂贵。如果您想检查更大的理想素数,这是有道理的,但是在这里?否:这会增加复杂性,因此我尝试使这些优化相当简单直接。
关于java - 如何找到第五个完美数(即33550336)?这个问题需要永远的解决,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65341267/
为了加速测试字谜字符串的快速输出行为,我 came up with基于质数的哈希方案——尽管它看起来像 I wasn't the first . 基本思想是将字母映射到素数,并计算这些素数的乘积。字母
我使用 Perfect Framework 创建了一个 Swift 3.0 服务器。一切都按预期进行得很好,但我正在尝试了解是否有更好的方法来做一些事情。 来自 iOS 背景,我知道总是在不同的线程中
我有一个固定大小的正方形 div,希望使用 CSS 在其中放置任意大小的图像,以便它在水平和垂直方向上都居中。横向很容易: .container { text-align: center } 对于垂直
程序员离不开终端,配置一个好看又好用的终端,可以提高工作效率. 本篇文章记录了使用 Oh My Zsh + PowerLevel9k + zsh插件 快速配置Ubuntu下默认终端的过程. 我们在
在请求处理程序中,处理例如获取 https://example.com/collections/1或 POSThttp://0.0.0.0:8080/collections 如何获取服务器地址 htt
我正在使用 perfect 和 SQLite司机和StORM作为连接器。我可以一一保存(创建)多行。为了使其更快,我想一次创建多行,我该怎么做? 最佳答案 从完美的 SQLite-StORM 和 Pe
这是我在这里的第一篇文章,所以我希望我提供所有正确的信息。 我目前正在开发一个简单的菜单应用程序,它有一个按钮控制数组(使用 MSDN 建议的控制数组的变通方法),我很难重新调整表单大小和将按钮居中。
在 androidplot XYPlot 中,如果您有较大的值(许多数字)和/或较大的字体大小,则 Y 轴上的刻度标签会被剪裁。这个(以及 X 轴上的类似问题)之前已经在这些问题中讨论过: Range
注意:我遗漏了不相关的代码 所以我目前正在研究 CCC 1996 P1,这个问题的全部目的是能够计算一个整数输入是完美数、不足数还是充数。我上面列出的代码可以工作,但是我认为它太慢了。该代码会迭代每个
我需要什么 我需要一个产生双射输出的算法。我有一个 31 位输入,需要一个伪随机 31 位输出。 我考虑过的 CRC 在其位宽内是双射的。 我查看了 Google 并找到了多项式,但找不到表格或算法。
我在 Ubuntu 14.04.1、clang-3.8 上使用 PerfectSwift我使用的是 Perfect,一切正常,但现在,我不能再编译了(但它可以在我的 mac 上编译) 错误日志是 /h
如果您对分表有以下痛点那么不妨试试我这边开源的框架sharding-core ,是否需要无感知使用分表组件,是否需要支持abp,是否需要支持自定义分表规则,是否需要支持自定义分表键,是否需要支持特定
我正在尝试确定我的 crc 与“ 理想 ”32 位 crc 的比较。 因此,我运行我的 crc 超过 100 万个完全随机的数据样本并收集了碰撞数量,我想将此数字与我可以从“ 理想 ”crc 中预期的
我正在开发一个项目,需要验证我的 URL,并偶然发现了以下正则表达式模式; /(((http|ftp|https):\/{2})+(([0-9a-z_-]+\.)+(aero|asia|biz|cat
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 4 年前。 Improve
我正在创建一个需要居中于中间的圆形网站。背景由围绕中心图像的圆圈组成。每当我以全屏(F11 快捷键)查看我的网站时,无论我的屏幕分辨率如何,它都完美居中。 如果我在没有全屏显示的情况下查看我的网站,我
所以我有一个网站,在开发人员工具中测试响应能力时看起来很棒,但在 iPhone 本身上实际测试时却没有居中并且看起来有些破烂。 什么会导致这种情况,如果我无法使用 iPhone(在我的 android
我有一个内部类,它扩展了 AbstractTableModel。 import javax.swing.table.AbstractTableModel; public class MyClass e
所以我正在使用 Perfect 服务器开发一个将值返回给客户端的应用程序。目前,它需要从另一个 API 下载一些数据,对其进行处理,然后将其发送给客户端。 然而,出于某种原因,它在 OSX 中编译良好
我有一些 CSS 按钮。 “按钮”效果是通过在 anchor 标记中使用固定大小的 元素来完成的,并且 css 规则以 a span:active 、 a span:hover 的形式显示按钮状态。
我是一名优秀的程序员,十分优秀!