我正在尝试找到可以被1到20之间的所有数字整除的最小正数。
我开始创建一个for循环来从1到20运行,然后我知道我必须创建另一个循环,将每个数字除以1到20之间的某个数字,如果这两个数字的模数是不是0,然后跳到下一个数字(即递增1),直到找到最小的数字。
public class Problem5 {
public static void main(String args[]){
for(int i=1;i<=20;i++){
for(int counter=1;variable length argument?;counter++){
if(i%counter==0){
System.out.println(counter);
}
}
}
}
}
我知道我需要第二个for循环从1计数到我需要的任何数字,所以我需要一个可变长度的参数,因为我不知道最小的数字是什么?
答案 0 :(得分:1)
你需要相反的循环,如果你愿意,你不需要检查% 1
可以使用最高素数的sastertart。如果它是4和5的倍数,它也必须是20的倍数;)
因为它必须是所有素数的倍数,所以你只需要检查2 * 3 * 5 * 7 * 11 * 13 * 17 * 19的倍数。这将使它更快,更快。
没有上限,因此您无需添加上限。如果您愿意,可以将其设为counter < Integer.MAX_VALUE
。
您可以计算出必然的因素,而不是使用蛮力。
public class CommonMultipleMain {
static final int MAX = Integer.getInteger("max", 1000);
public static void main(String... ignored) {
// warmup
getLowestMultipleOf(60);
long start = System.nanoTime();
BigInteger bi = getLowestMultipleOf(MAX);
long time = System.nanoTime() - start;
System.out.println("Smallest number which has factors up to " + MAX + " took " + time / 1000 + " us, is " + bi);
}
private static BigInteger getLowestMultipleOf(int max) {
int[] maxFactorCount = new int[max + 1];
for (int i = 2; i <= max; i++) {
int[] factors = getFactorsFor(i);
for (int j = 2; j < factors.length; j++)
if (maxFactorCount[j] < factors[j])
maxFactorCount[j] = factors[j];
}
BigInteger bi = BigInteger.ONE.shiftLeft(maxFactorCount[2]);
for (int i = 3; i <= max; i += 2) {
int exponent = maxFactorCount[i];
switch (exponent) {
case 0:
break;
case 1:
bi = bi.multiply(BigInteger.valueOf(i));
break;
default:
bi = bi.multiply(BigInteger.valueOf(i).pow(exponent));
break;
}
}
return bi;
}
private static int[] getFactorsFor(int i) {
int[] factors = new int[i + 1];
while ((i & 1) == 0) {
i >>= 1;
factors[2]++;
}
for (int j = 3; j * j <= i; j += 2) {
while (i % j == 0) {
i /= j;
factors[j]++;
}
}
if (i > 1)
factors[i]++;
return factors;
}
}
打印
,其具有因素高达1000把15005我们最小数目,是7128865274665093053166384155714272920668358861885893040452001991154324087581111499476444151913871586911717817019575256512980264067621009251465871004305131072686268143200196609974862745937188343705015434452523739745298963145674982128236956232823794011068809262317708861979540791247754558049326475737829923352751796735248042463638051137034331214781746850878453485678021888075373249921995672056932029099390891687487672697950931603520000
要计算到这个数字需要比宇宙年龄更长的时间,但通过计算,它需要的时间少于闪烁所需的时间。
答案 1 :(得分:1)
答案很容易计算,没有暴力迭代所有整数,直到你找到答案:
Num Factors
2 2
3 3
4 2 already have one '2', need only one more
5 5
6 already have 2 & 3
7 7
8 2 already have 2 '2's, need only one more
9 3 already have one '3', need only one more
10 already have 2 and 5
11 11
12 already have 2 '2's and a '3'
13 13
14 etc...
15
16 2
17 17
18
19 19
20
将第二列中的所有数字相乘。用Java实现是一种练习。
答案 2 :(得分:0)
int eulersmallestNumber(int value){
int start = 1;
boolean found = false;
while(!found){
found = eulerhelper(start,value);
start++;
}
return start;
}
boolean eulerhelper(int start, int value){
for(int i=1;i<=value;i++){
if(i%start != 0) return false;
}
return true;
}
你给eulersmallestNumber
一个你希望它循环的最大数字,例如10。
它将解决这个问题。
2520是可以除以每个数字的最小数字 从1到10没有任何余数。
工作原理。
它从起始值1开始递增,并调用返回布尔值的函数eulerhelper。 (当eulerhelper返回true时,循环将退出)
eulerhelper获取值并除以所有值1 - value
。如果其中一个值有提醒,则返回false。但是,如果这些数字之间的所有值都没有提醒,它将返回true。
答案 3 :(得分:0)
从你的方法开始,你需要一直到i / 2(或理想的是sqrt(i))。所以我们会得到(我们跳过):
(编辑:修订和更正的代码)
int i,j,mult;
int smallest = 2; // Start with 2
for (i = 3; i <= 20; i++)
{
if (smallest % i == 0) // Already divisible
continue;
mult = i;
// We try to divide every number from 2 to 20 with
// the numbers before it, so that we skip repeating
// prime factors and get the smallest numbers
for (j = 2; j <= sqrt(i); j++)
{
// j too high
if (mult / j == 0)
break;
if (mult % j == 0)
mult /= j;
}
// mult will be 1 if the current number is a product
// of 2 or more numbers before it
smallest *= mult;
}
printf("%d\n", smallest);
这是C,但你应该理解它很好。要进行检查,请从1到20中取所有数字并写出其素数因子分解。然后以最高权力取所有素数并乘以它们。它应该是232792560