您的位置:首页 > 编程语言

编程之美 -- 2.7 最大公约数问题

2015-04-10 09:32 197 查看


题目描述

求解X 和 Y 的最大公约数f(x, y)

解法一:

使用辗转相除法,f(x, y) = f(y, x % y), x 和 y 数字偏大则取模运算偏多而开销大

解法二:相减法,f(x,y) = f(x-y,y) , (x > y)。 可以解决取模开销问题,但是相对减法则迭代次数偏多

解法三:结合以上两种优势,如果每次递归求解时

1、同为偶数,则f(x,y) = 2 * f(x, y)

2、x奇数y偶数,则f(x,y) = f(x>>1, y)

3、y奇数x偶数,则f(x,y) = f(x,y>>1)

4、同为奇数,则f(x, y) = f(x-y, y), x>y

package chapter_2_binary;

import java.util.Scanner;

/**
* @author LiangGe
*
*	求解x和y的最大公约数
*
*/
public class question_2_7_1 {

/**
* @param x
* @param y
* @return
*
* 直接使用相除法
*
*/
public static long gcd(long x, long y) {
return (y == 0) ? x : gcd(y, x % y);
}

/**
* @param x
* @param y
* @return
* x和y的最大公约数同时也是 x-y 和 y的最大公约数
* 使用相减法,可以避免数字很大时候的除法运算
*
*/
public static long bigGcd(long x, long y) {
if(x < y) {
return bigGcd(y, x);
} else if(y == 0) {
return x;
} else {
// 迭代次数太多,如果10000000 1 则计算效率降低
return bigGcd(x - y, y);
}
}

/**
* @param x
* @param y
* @return
*
* 结合以上两种方式的优势
* 根据x和y的奇偶性质,简化计算方式
*
*/
public static long bigGcd2(long x, long y) {
if(x < y) {
return bigGcd2(y, x);
} else if(y == 0) {
return x;
} else {
if(x % 2 == 0) {
if(y % 2 == 0) {
// 如果x和y都是偶数,则gcd(x,y) = 2*(x/2,y/2)
return 2 * bigGcd2(x>>1, y>>1);
} else {
return bigGcd2(x>>1, y);
}
} else {
if(y % 2 == 0) {
return bigGcd2(x, y>>1);
} else {
return bigGcd2(x - y, y);
}
}
}
}

public static void main(String args[]) {
Scanner scanner = new Scanner(System.in);
long num = scanner.nextLong();
scanner.nextLine();

while (num-- > 0) {
long x = scanner.nextLong();
long y = scanner.nextLong();

System.out.println("(" + x + ", " + y + ") 最大公约数 = " + gcd(x, y));
System.out.println("(" + x + ", " + y + ") 最大公约数 = " + bigGcd(x, y));
System.out.println("(" + x + ", " + y + ") 最大公约数 = " + bigGcd2(x, y));
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  编程之美