算法学习笔记(1)最大公约数与最小公倍数

目录

最大公约数(gcd)

基本原理

方法与实现

1.穷举法

2.短除法

3.辗转相除法(欧几里得算法)

4.更相减损法 (九章算术)

 5.Stein算法

最小公倍数(lcm)

基本原理

方法与实现 

1.穷举法

2.进阶穷举法

3.短除法 

4.借助最大公约数求最小公倍数


 

  • 最大公约数(gcd)


    基本原理

                gcd(x,x)=x                (两个相同数的最大公约数就是这个数本身)

                gcd(0,x)=x                (0与另一个数x的最大公约数就是x)

                gcd(x,y)=gcd(y,x)      (x和y的最大公约数与y和x的最大公约数相同)


方法与实现

        1.穷举法

                从两者中较小者开始递减,直至出现两者公因数

        2.短除法

                原理:将两数的所有公因子找出来相乘,结果就是两个数的最大公约数

                1.f=1

                2.利用循环变量i从2开始递增至min(x,y)

                        每次循环内部判断i是否是x和y的公因子

                        若是:f*=i;

                                   x/=i;y/=i;

                3.返回f;

                实现:

int gcd(int x,int y){
    int f = 1;
    for(int i=2;i<=x && i<=y;i++){
        while(m%i==0 && n%i==0){
            f*=i;
            x/=i;
            y/=i;
        }
    }
    return f;
}

3.辗转相除法(欧几里得算法)

        原理:

                gcd(x,y)=gcd(y,x%y)  其中x>y

         1.如果y=0,计算结束,x就是最大公约数

         2.否则,计算x除y的余数,让x=y,y=余数

         3.回到1

         实现

int gcd(int x,int y){
	int s;
	while(y){//当y不等于0时
		s=x%y;
		x=y;
		y=s;
	}
	return x;
}

        递归实现 :

int gcd(int x,int y){
	if(y==0)
        return 0;
    else 
	    return gcd(y,x%y);
}

4.更相减损法 (九章算术)

        原理:(本质与辗转相除相同,当两数差值较大时,辗转相除运算次数更少)

     gcd(x,y)=gcd(y,x%y)  其中x>y

        辗转相除法取余,更相减损法取差

int gcd(int x,int y){
	int s;
	while(y){//当y不等于0时
		s=(x-y>0)?x-y:y-x;//取两者差的正值
		x=y;
		y=s;
	}
	return x;
}

 5.Stein算法

        当两个数字非常大时,除法运算对于计算机十分复杂,消耗很多CPU时间,Stein算法通过移位运算和加减避免了大量除法运算

        原理

        gcd(kx,ky)=k*gcd(x,y)

        当k与y互质时,gcd(kx,y)=gcd(x,y)

         1.计数器c=0;

         2.当两数皆为偶数时,同时>>1;c++

            当两数一个是奇数,一个是偶数时,偶数>>1;

            当两数皆为奇数时,利用更相减损法一次;

         3.重复执行步骤2直至两数相等

         4.得到的相同的那个数<<c(相当于乘2的c次方),结果即为最大公约数

        实现 

int stein(int x,int y){
	int c = 0;
	if (x==0)
		return y;	//若x为0,y为最大公约数 
	if (y==0)
		return x;
	while (y) {	//y不等于0时 
		if(x&1==0){			//x为偶数 
			x>>1;			//x右移一位,相当于除2 
			if(y&1==0){
				y>>=1;		//y右移一位 
				c++;		//计数加一 
			}				
		}else if(y&1==0)	//x为奇数,y为偶数 
			y>>=1;
		else{				//x,y 皆为奇数 
			int s =(x-y>0)?x-y:y-x;
			x=y;
			y=s;
		}	
	}
	return (x<<c);	//返回x左移c位的值 
}

        递归实现 

int stein(int x,int y){	
	if (x==0)
		return y;	
	if (y==0)
		return x;
	if( (x&1==0) && (y&1==0) )		//x,y 皆为偶数
		return stein(x>>1,y>>1)<<1;
	else if( (x&1) && (y&1==0) )	//x为奇数,y为偶数
		return stein(x,y>>1);
	else if( (x&1==0) && (y&1) )	//x为偶数,y为奇数
		return stein(x>>1,y);
	else 							//x,y 皆为奇数
		return stein(abs(x-y),y);	//abs函数,求整型绝对值。需配合头文件math.h或stdilb.h使用		 
}

  • 最小公倍数(lcm)

        基本原理

        gcd(x,y) * lcm(x,y) = x*y

        方法与实现 

1.穷举法

从两数较大者开始递增,直至出现两数的公倍数

2.进阶穷举法

        从x, 2*x, 3*x依次倍增,每次判断是否是另一个数的倍数(x>y)

        实现

int lcm(int x,int y){	
	if (x<y){
		int s=x;
		x=y;
		y=s;
	}
	int i;
	for(i=0; ;i++){
		if(x*i%y==0)
			return i*x;
	}
}

3.短除法 

4.借助最大公约数求最小公倍数

        基本原理:gcd(x,y) * lcm(x,y) = x*y

                        =>lcm(x,y)=x*y/gcd(x,y)



 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值