编程之美之最大公约数

问题:求两个整数的最大约数

方法一:

       辗转相除法,对于两个整数x和y,用f(x,y)表示两者的最大公约数,则f(x,y)=f(y,x%y)。

       例如f(42,30)=f(30,12)=f(12,6)=f(6,0),即有最大公约数6。

代码如下:

import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner mScanner=new Scanner(System.in);
		String[] mArrs= mScanner.nextLine().trim().split(" ");
		int mFirst=Integer.valueOf(mArrs[0]);
		int mSecond=Integer.valueOf(mArrs[1]);
		mScanner.close();
		
		System.out.println(gcdFun(mFirst,mSecond));
	}

	private static int gcdFun(int mFirst,int mSecond) {
		int mMax=(mFirst>mSecond)?mFirst:mSecond;
		int mMin=(mFirst>mSecond)?mSecond:mFirst;
		if(mMin==0)
			return mMax;
		return gcdFun(mMax%mMin,mMin);
	}
}

方法二:

        对于方法一中,由于采用取模运算开销较大,我们将方法一进行改进。采用减法,即f(x,y)=f(x-y,y)。

        例如f(42,30)=f(30,12)=f(12,18)=f(18,12)=f(6,6)=f(6,0)即有最大公约数6。

代码如下:

import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner mScanner=new Scanner(System.in);
		String[] mArrs= mScanner.nextLine().trim().split(" ");
		int mFirst=Integer.valueOf(mArrs[0]);
		int mSecond=Integer.valueOf(mArrs[1]);
		mScanner.close();
		
		System.out.println(gcdFun(mFirst,mSecond));
	}

	private static int gcdFun(int mFirst,int mSecond) {
		int mMax=(mFirst>mSecond)?mFirst:mSecond;
		int mMin=(mFirst>mSecond)?mSecond:mFirst;
		if(mMin==0)
			return mMax;
		return gcdFun(mMax-mMin,mMin);
	}
}

方法三:

        对于方法二,采用减法增加了迭代的次数,我们将两种方法混合使用得到解法三。

        1、对于y和x,如果y=k*y1,x=k*x1。那么有f(y,x)=k*f(y1,x1)

        2、如果x=p*x1,假设p为素数,并且y%p!=0。则有f(y,x)=f(y,p*x1)=f(y,x1)。

       这里取p=2。对x和y分奇数和偶数进行4种情况讨论。

       代码如下:

import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner mScanner=new Scanner(System.in);
		String[] mArrs= mScanner.nextLine().trim().split(" ");
		int mFirst=Integer.valueOf(mArrs[0]);
		int mSecond=Integer.valueOf(mArrs[1]);
		mScanner.close();
		
		System.out.println(gcdFun(mFirst,mSecond));
	}

	private static int gcdFun(int mFirst,int mSecond) {
		int mMax=(mFirst>mSecond)?mFirst:mSecond;
		int mMin=(mFirst>mSecond)?mSecond:mFirst;
		boolean isMaxEven=isEven(mMax);
		boolean isMinEven=isEven(mMin);
		if(mMin==0)
			return mMax;
		else
		{
			if(isMaxEven&&isMinEven){
			return gcdFun(mMax>>1,mMin>>1);
			}else if (isMinEven&&!isMaxEven) {
				return gcdFun(mMax, mMin>>1);
			}else if (!isMinEven&&isMaxEven) {
				return gcdFun(mMax>>1, mMin);
			}else {
				return gcdFun(mMax-mMin, mMin);
			}
		}
		
	}

	private static boolean isEven(int mMax) {
		if((mMax&1)==0)
			return true;
		return false;
	}
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值