[英]Greatest Common Divisor (GCD) by Euclidean algorithm in Java
我為 Greatest Common Divisor-GCD 編寫了這段代碼。 I subtract smaller integer from bigger integer, then I remove biggest integer and subtract smaller integer from bigger integer again until two integers are equal and it's result. 我想知道這是否正確,是否可以更簡單? 謝謝你。
public static void main(String[] args) {
int firstInteger=114, secondInteger=67;
if (firstInteger>secondInteger) {
int result=firstInteger-secondInteger;
while (firstInteger != secondInteger) {
if (secondInteger > result) {
firstInteger = secondInteger;
secondInteger = result;
result = firstInteger - secondInteger;
} else {
firstInteger = result;
result = firstInteger - secondInteger;
}
}
System.out.println(firstInteger);
}
else {
int result=secondInteger-firstInteger;
while (secondInteger!=firstInteger) {
if (firstInteger>result) {
secondInteger=firstInteger;
firstInteger=result;
result=secondInteger-firstInteger;
}
else {
secondInteger=result;
result=secondInteger-firstInteger;
}
}
System.out.println(secondInteger);
}
}
態度是正確的,代碼將按預期 function 但是,如果將 0 作為值應用於firstInteger
或secondInteger
,它將失敗(鎖定到連續循環)。 這同樣適用於帶符號的 integer 值。 如果它們出現,您將需要處理這些情況。
盡管代碼對於它打算完成的任務來說相當長,但它確實有效。 如果您使用不同的概念來處理任務,則可以大大縮短它,例如,通過使用 模(%) 運算符(又名:余數運算符)並執行一種除法形式來查看是否有余數,而不是執行減法,並忽略哪個參數值開始時更大。 這是一個實際上可以用作方法的示例:
public static int getGreatestCommonDivisor(int numerator, int denominator) {
if (numerator <= 0 || denominator <= 0) {
System.err.println("getGreatestCommonDivisor() Method Error! A value of "
+ "zero (0) or less can not be supplied as an argument!");
return -1;
}
int temp = numerator % denominator;
while (temp > 0) {
numerator = denominator;
denominator = temp;
temp = numerator % denominator;
}
return denominator;
}
如果要在方法內部處理帶符號的參數值,則可以使用Math#abs()方法,該方法返回int值的絕對(正)值。 此方法給出參數的絕對值。 參數可以是 int、double、long 和 float,但對於這種方法,我們只關心int類型 arguments。 這是一個例子:
public static int getGreatestCommonDivisor(final int numerator, final int denominator) {
if (numerator == 0 || denominator == 0) {
System.err.println("greatestCommonDivisor() Method Error! A value of "
+ "zero (0) can not be supplied as an argument!");
return -1;
}
int num = numerator;
num = Math.abs(numerator); // Ensure an absolute value
int gcd = Math.abs(denominator); // Ensure an absolute value
int temp = num % gcd;
while (temp > 0) {
num = gcd;
gcd = temp;
temp = num % gcd;
}
return gcd;
}
您的代碼確實有效。 以下是我編寫的程序。
public int calculateGCD(int highNumber, int lowNumber){
boolean GCDFound = false;
int quotient, remainder, GCD = 1;
while(!GCDFound)
{
quotient = highNumber / lowNumber;
remainder = Math.floorMod(highNumber, lowNumber);
if(remainder == 0)
{
GCD = lowNumber;
GCDFound = true;
}
else
{
highNumber = lowNumber;
lowNumber = remainder;
}
}
return GCD;
}`
沒有錯誤處理。 兩個數字都不是零或減去什么。
我對您的 (kamilP) 代碼和我的代碼完成了三個測試。 每個測試使用 1,000,000 對數字的二維數組。 第一個數組編號介於 1 和 107,374,143 之間,第二個數組編號介於 107,374,143 和 2,147,483,646 之間,第三個數組編號介於 1 和 2,147,483,646 之間。 測試程序通過數組到 go 需要多長時間。
結果如下(以毫秒為單位):KamilP & CombatWomble
這是我讓它變得更簡單和更快的方法。
如果它可以變得更簡單?
有幾種方法可以簡化它。 這里有三個。
JMH
之類的東西。r
和s
的順序無關緊要。在您的方法中,我使用了一個循環並更正了這兩個值,以確保在減法過程中得到積極的結果。
public static int gcd(int r, int s) {
// absolute value of r and s
r = r > 0 ? r : -r;
s = s > 0 ? s : -s;
while (s > 0) {
// find min(r,s)
int t = r > s ? s : r;
// find max(r,s)
r = r > s ? r : s;
s = t;
r = r - s;
}
return r;
}
第二種方法是簡單的迭代,可能是最有效的。 但是,必須在歸還 GCD 之前更正該標志。
public static int gcd(int r, int s) {
while (s != 0) {
int t = r % s;
r = s;
s = t;
}
return r > 0 ? r : -r;
}
這是遞歸方法。 再次需要更正該標志。
public static int gcd(int r, int s) {
if (s != 0) {
return gcd(s, r % s);
}
return r > 0 ? r : -r;
}
這是對順序和符號可能變化的測試。
System.out.println(gcd(24, 36));
System.out.println(gcd(-24, 36));
System.out.println(gcd(24, -36));
System.out.println(gcd(-24, -36));
System.out.println(gcd(36, 24));
System.out.println(gcd(-36, -24));
System.out.println(gcd(36, -24));
System.out.println(gcd(-36, 24));
所有三種方法都打印。
12
12
12
12
12
12
12
12
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.