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。

用辗转相除法求几个数的最大公约数,可以先求出其中任意两个数的最大公约数,再求这个最大公约数与第三个数的最大公约数,依次求下去,直到最后一个数为止。最后所得的那个最大公约数,就是所有这些数的最大公约数。

更相减损法

更相减损法:也叫更相减损术

第一步:任意给定两个正整数;判断它们是否都是偶数。若是,则用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。
这个过程可以简单的写为:
(98,63)=(35,63)=(35,28)=(7,28)=(7,21)=(7,14)=(7,7)=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。
这个过程可以简单地写为:
(260,104)(/2/2) =>(65,26)=(39,26)=(13,26)=(13,13)=13. (*2*2) => 52 [1]

比较:

比较辗转相除法与更相减损术的区别

(1)都是求最大公因数的方法,计算上辗转相除法以除法为主,更相减损术以减法为主,计算次数上辗转相除法计算次数相对较少,特别当两个数字大小区别较大时计算次数的区别较明显。

(2)从结果体现形式来看,辗转相除法体现结果是以相除余数为0则得到,而更相减损术则以减数与差相等而得到


代码实现

一:最简单方法

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int m, n,temp,i;
    scanf("%d", &m);
    scanf("%d", &n);

    if (m>n)
    {
        temp = m;
        m = n;
        n = temp;
    }

    for (i = m; i >= 1;i--)
        if (m%i==0 && n%i==0)
            break;

    printf("%d\n", i);

    system("pause");
    return 0;
}

二:辗转相除法(递归)

#include <stdio.h>
#include <stdlib.h>

int gcd(int a, int b)
{
    int mod;
    if ((mod = a % b) == 0)
        return b;
    return gcd(b, mod);
}

int main()
{
    int m, n,ret;
    scanf("%d", &m);
    scanf("%d", &n);

    ret = gcd(m, n);
    printf("%d", ret);

    system("pause");
    return 0;
}

三:辗转相除法(非递归)

int gcd(int a, int b)
{
    int mod=a % b;
    while (mod!=0)
    {
        a = b;
        b = mod;
        mod = a % b;
    }
    return b;
}

四:更相减损法(非递归)

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int gcd(int a, int b)
{
    int val= a - b;
    while (val != b)
    {
        if (b>val)
        {
            a = b;
            b = val;
        }
        else
        {
            a = val;
        }
        val = a - b;
    }
    return val;
}

int main()
{
    int m, n,ret,temp,count=0;
    scanf("%d", &m);
    scanf("%d", &n);

    if (m == n)
    {
        printf("%d", m);
        return 0;
    }

    if (m < n)
    {
        temp = m;
        m = n;
        n = temp;
    }

    while (m%2 == 0 && n%2 == 0)
    {
        count++;
        m /= 2;
        n /= 2;
    }

    ret = gcd(m, n);
    printf("%d", ret*((int)pow(2,count)));  //使用pow需要进行(int)转换,不然会报错

    system("pause");
    return 0;
}

原文地址:https://www.cnblogs.com/ssyfj/p/9376945.html

时间: 2024-10-23 20:46:20

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

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

问题:给出两个数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

【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

更相减损术求最大公约数-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语言】两个指针(地址)相减

两个指针相减,为两个指针之间间隔这两个指针类型的数目. 如:int *p,*q; p-q=(p地址-q地址)/sizeof(int) #include <stdio.h> int main() { int a[9]={1,2,3,4,5,6,7,8,9}; char *p,*q; int *p2,*q2; p=(char*)a; q=(char*)&a[2]; printf("p=%08X q=%08X a[%d]=%d\n",p,q,q-p,a[q-p]); //

C语言复习---获取矩阵的对角和

#include <stdio.h> #include <stdlib.h> #include <math.h> #define MAX 5 int main() { int a[MAX][MAX] = { 0 }; int total = 0; //初始化数据 for (int i = 0; i < MAX; i++) { for (int j = 0; j < MAX;j++) { a[i][j] = rand() % 100; } } //显示数据 f

运用Python语言编写获取Linux基本系统信息(三):Python与数据库编程,把获取的信息存入数据库

运用Python语言编写获取Linux基本系统信息(三):Python与数据库编程 有关前两篇的链接: 运用Python语言编写获取Linux基本系统信息(一):获得Linux版本.内核.当前时间 运用Python语言编写获取Linux基本系统信息(二):文件系统使用情况获取 一.实验环境: Python2.7.10.pycharm.VM虚拟机.CentOS6.3.mysql 二.MySQLdb模块: MySQLdb模式是Python中专门连接MySQL数据库的模块,另外Python开发环境的搭

Swift3.0语言教程获取C字符串

Swift3.0语言教程获取C字符串 Swift3.0语言教程获取C字符串,为了让Swift和C语言可以实现很好的交互,开发者可以使用NSString的cString(using:)方法在指定编码格式后,获取C字符串,其语法形式如下: func cString(using: UInt) 其中,using用来指定编码格式. [示例1-19]以下将使用cString(using:)方法获取C字符串. import Foundation var str1=NSString(string:"Hello&

Swift3.0语言教程获取字符串编码与哈希地址

Swift3.0语言教程获取字符串编码与哈希地址 Swift3.0语言教程获取字符串编码与哈希地址,以下将讲解字符串中其它内容的获取方法. 1.获取字符串编码 在NSString中可以使用2个属性获取字符串编码,分别为availableStringEncodings属性和defaultCStringEncoding属性. (1)availableStringEncodings属性可以用来获取NSString可用的字符串编码.其语法形式如下: class var availableStringEn

C# 语言如何获取json格式的数据,不用javascript用c#实现。。。

{'state' : 1,'data':{'list':[{'id': 123, 'name': '诸葛天邪','level': 10,'country': 1,}]}} 比如我要获取里面的 id 该如何实现. 我有更好的答案 分享到: 按默认排序 | 按时间排序 2条回答 2012-06-25 20:15yzy_130 | 七级 最快回答 首先这个json串有几个错误的地方 第一个非常重要的错误,json串里面只能用双引号,不能用单引号,这个单双引号表示的意思不是引号内是字符串,而是json的