更新减损术的Java实现

先来介绍下这个名词的来源:

 摘自百度百科:

九章算术》是中国古代的数学专著,其中的“更相减损术”可以用来求两个数的最大公约数,原文是:可半者半之,不可半者,副置分母、子之数,以少减多,更相减损,求其等也。以等数约之。

白话文译文:

(如果需要对分数进行约分,那么)可以折半的话,就折半(也就是用2来约分)。如果不可以折半的话,那么就比较分母和分子的大小,用大数减去小数,互相减来减去,一直到减数与差相等为止,用这个相等的数字来约分。

使用步骤

编辑

第一步:任意给定两个正整数;判断它们是否都是偶数。若是,则用2约简;若不是则执行第二步。

第二步:以较大的数减较小的数,接着把所得的差与较小的数比较,并以大数减小数。继续这个操作,直到所得的减数和差相等为止。

则第一步中约掉的若干个2与第二步中等数的乘积就是所求的最大公约数。

其中所说的“等数”,就是最大公约数。求“等数”的办法是“更相减损”法。

使用实例:

例1、用更相减损术求98与63的最大公约数

解:由于63不是偶数,把98和63以大数减小数,并辗转相减

98-63=35

63-35=28

35-28=7

28-7=21

21-7=14

14-7=7

所以,98和63的最大公约数等于7。

例2、用更相减损术求260和104的最大公约数。

解:由于260和104均为偶数,首先用2约简得到130和52,再用2约简得到65和26。

此时65是奇数而26不是奇数,故把65和26辗转相减

65-26=39

39-26=13

26-13=13

所以,260与104的最大公约数等于13乘以第一步中约掉的两个2,即13*2*2=52。

以下是我自己根据算法做的一个实现,比较繁琐,但是可以实现功能,先放在这里,有更好的想法再更新

package com.henu.test;

import java.util.HashMap;
import java.util.Map;

public class MathDemo {

    public static void main(String[] args) {
        //在这里输入你要求的两个数
        Map<String, Object>  map = math(98,63);
        for(Map.Entry<String, Object> entry:map.entrySet()){
            System.out.println(entry.getKey()+"----"+entry.getValue());
        }

    }
    /**
     * 更相减损术
     * @param a
     * @param b
     * @return
     */
    public static Map<String, Object> math(int a, int b){
        Map<String, Object>  map = new HashMap<>();
        int count = 0;
        int temp = 0;
        int max =0;
        for(;a%2==0 && b%2==0;){
            a=a/2;
            b=b/2;
            count++;
        }
        out :
        while((a-b>0 && a-b !=b) ||(b>a && b-a != a) || a == b || b-a == a || a - b == b){
//        while(a-b==0 || b-a==0){
        if (a == b ) {
            temp = b;
            break out;
        }else if ( b>a && b-a != a) {
            temp = b-a;
            b = temp;
        }else if (a-b>0 && a-b !=b) {
            temp = a-b;
            a = temp;
        }else if (b-a == a ) {
            temp = a;
            break out;
        }else if (a - b == b ) {
            temp = b;
            break out;
        }
        }
        max = (int) Math.pow(2, count) * temp;
        //计算到最后a的值
        map.put("a", a);
        //计算到最后b的值
        map.put("b", b);
        //表示共同被2整除的次数
        map.put("count", count);
        //最后求得的最大公约数
        map.put("max", max);
        return map;
    }
}

原文地址:http://www.cnblogs.com/xiaoguaishou/p/7190489.html

时间: 2024-10-09 03:53:05

更新减损术的Java实现的相关文章

[SDOI2009][BZOJ1876] SuperGCD|高精度|更相减损术

1876: [SDOI2009]SuperGCD Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 1970  Solved: 663[Submit][Status][Discuss] Description Sheng bill有着惊人的心算能力,甚至能用大脑计算出两个巨大的数的GCD(最大公约 数)!因此他经常和别人比赛计算GCD.有一天Sheng bill很嚣张地找到了你,并要求和你比 赛,但是输给Sheng bill岂不是很丢脸!所以你决定写一个

更相减损术求最大公约数-C

可参照辗转相除 1 #include<stdio.h> 2 3 int main(void) 4 { 5 int x=260; 6 int y=104; 7 8 int temp; //临时变量 9 10 int index=0; 11 while((x%2==0)&&(y%2==0)) 12 { 13 x/=2; 14 y/=2; 15 ++index; 16 } 17 18 while(x!=y) 19 { 20 temp=x-y; 21 if(temp<y) 22

C语言复习---获取最大公约数(辗转相除法和更相减损法)

源自:百度百科 辗转相除法 辗转相除法:辗转相除法是求两个自然数的最大公约数的一种方法,也叫欧几里德算法. 例如,求(319,377): ∵ 319÷377=0(余319) ∴(319,377)=(377,319): ∵ 377÷319=1(余58) ∴(377,319)=(319,58): ∵ 319÷58=5(余29) ∴ (319,58)=(58,29): ∵ 58÷29=2(余0) ∴ (58,29)= 29: ∴ (319,377)=29. 用辗转相除法求几个数的最大公约数,可以先求出

求两个数的最大公约数,辗转相除法与更相减损法(递归迭代)

问题:给出两个数a和b,求出他们的最大公约数(greatest common divisor). 解法一:辗转相除法,又叫欧几里得算法.两个正整数a和b(a>b),他们的最大公约数等于a除以b的余数和b之间的最大公约数. 比如10和25,25除以10余5,那么10和25的最大公约数等同于5和10之间的最大公约数. //辗转相除法 递归解法 int gcd(int a,int b){ if(a%b==0) return b; return (b,a%b); } //辗转相除法 迭代解法int gc

BZOJ 1876: [SDOI2009]SuperGCD( 更相减损 + 高精度 )

更相减损,要用高精度.... --------------------------------------------------------------- #include<cstdio> #include<cstring> #include<cctype> #include<algorithm> using namespace std; const int maxn = 10009; char S[maxn]; int Power[maxn]; stru

【C语言】最大公约数(更相减损法)和(辗转相除法)

#include<stdio.h> #include <math.h> /* 编写一个函数,传入a,b两个int类型的变量,返回两个值的最大公约数. 例如:输入传入(0 , 5)函数返回5,传入(10 , 9)函数返回1,传入(12 , 4)函数返回4 */ //更相减损法 int fuc(int m,int n) { int i=0,temp,x; while(m%2==0 && n%2==0) //判断m和n能被多少个2整除 { m/=2; n/=2; i+=1

【安卓】数据库基于脚本的&quot;增量更新&quot;,每次更新时不需修改java代码、!

思路: 1.当然是基于SQLiteOpenHelper.onCreate(第一次安装程序时调用).onUpdate(升级程序时调用) 2.用"脚本"(脚本制作具体方法问度娘)做数据库升级,文件名标识对应版本,java中根据"上一版本.当前版本"选择执行的脚本. 升级时,修改DB_VERSION(当前版本)即可. DBManager.java: package com.example.test; import java.io.ByteArrayOutputStream

【安卓】数据库基于脚本的&amp;quot;增量更新&amp;quot;,每次更新时不需改动java代码、!

思路: 1.当然是基于SQLiteOpenHelper.onCreate(第一次安装程序时调用).onUpdate(升级程序时调用) 2.用"脚本"(脚本制作详细方法问度娘)做数据库升级,文件名称标识相应版本号,java中依据"上一版本号.当前版本号"选择运行的脚本. 升级时,改动DB_VERSION(当前版本号)就可以. DBManager.java: package com.example.test; import java.io.ByteArrayOutput

求两个数的最大公约数

求两个数的最大公约数 问题:给定两个正整数a和b,求他们的最大公约数. 最简单的方法就是穷举法,如果a>b,那么依次计算1~b的所有整数是否是a和b的公约数. public static void main(String[] args) { long timer = System.currentTimeMillis(); System.out.println(getGCB(1000234234,1242342390)); System.out.println(System.currentTime