[英]Program using loops for math purpose. (Java)
讓我解釋一下這個問題。
我需要編寫一個程序,在其中輸入數字N,然后必須找到可被所有數字整除為1的最小數字。
例如:。 如果我的N為5,則答案為60。60被5、4、3、2和1整除。
這是我到目前為止所擁有的...
import java.util.Scanner;
public class Questão_04 {
public static void main (String [] args)
{
int x = 1, n = 1, d = x % n;
System.out.print("Enter N: ");
Scanner in = new Scanner(System.in);
n = in.nextInt();
do
{
if (d != 0)
{
x = x + 1;
do
{
n = n -1;
} while (n != 0);
}
else
{
do
{
n = n - 1;
} while (d != 0);
}
} while (n != 0);
System.out.print(x);\\the minimum number divisible by N and all up to N.
}
終於,經過一段時間的努力,我終於找到了一個有效的解決方案:
public int smallestMatching(int n){
ArrayList<Integer> divisors = new ArrayList<>();
for(int i = 2 ; i <= n ; i++){
int tmp = i;
//simplify div, until it can't be created by multiplying elements of divisors
for(int div : divisors)
if(tmp % div == 0)
tmp /= div;
if(tmp != 1)
//tmp cant be generated from number that are content of divisors
//-> add to divisors
{
divisors.add(tmp);
}
}
//calculate the final result
int result = 1;
for(int div: divisors)
result *= div;
return result;
}
喜歡這個問題:D。
查找此值的有效算法僅考慮小於或等於N的素數。
v = 1
開始 N
p_i
q_i
使得p_i ^ q_i <= N
v *= p_i ^ q_i
對於您的示例N = 5,素數為2,3,5和
所以v = 2 ^ 2 * 3 * 5 = 60
對於N = 18,您最終得到
v = 2 ^ 4 * 3 ^ 2 * 5 * 7 * 11 * 13 * 17
唯一棘手的問題是生成小於N的素數。
但是,由於v隨着N的增加而快速增長( O(N!)
或O(N^log(N))
或類似的東西),您將在N的某個較低值(在幾百個?)這意味着您可能可以避免預先計算一張小的素數表。 (除非您使用任意精度數字類型)
我猜您正在嘗試計算f(n) = lcm(1,2,...,n)
。 我認為該函數似乎在n
較小時迅速增長,盡管隨着質數空間的逐漸縮小,它最終可能會逐漸減小。 理論上說ln f(n)/n
漸近於1
,因此f(n)
大致呈指數增長。
我們可以通過注意lcm(1,2,...,n)
= lcm(lcm(1,2,...,n-1),n)
來簡化,因此f(n)
可以遞歸計算。 此外, lcm(a,b) = a*b/gcd(a,b)
因此我們可以根據標准gcd
函數編寫遞歸。 我建議遞歸計算f
如下: f(n+1) = f(n) / gcd(f(n),n+1) * (n+1)
。 在相乘之前進行除法可減小中間結果的大小。 gcd
均分f(n)
因此整數除法很好。 您可以記住f(n)
來加快計算速度,盡管如果僅計算一個n
f(n)
不會有幫助。
我已經在下面的Java中實現了該功能。 它以我能達到的速度運行,至少直到堆棧大小溢出為止,在我的計算機上大約為n=10000
。 您可以重組以使用迭代代替遞歸,這可能會使最大值n
更高。 (基於類似的情況,我猜想它在計算機上的n=50000
左右會用完內存,但是我實際上沒有嘗試過。)
import java.math.BigInteger;
public class LCM {
public static BigInteger f(int n) {
if (n == 1) return BigInteger.ONE;
BigInteger prev = f(n-1);
return prev.divide(prev.gcd(BigInteger.valueOf(n)))
.multiply(BigInteger.valueOf(n));
}
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
System.out.println("f(" + n + ") = " + f(n));
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.