当前位置: 首页 > article >正文

几种详细的最大公约数的求法

最大公因数(Greatest Common Divisor,GCD)是指两个或多个整数共有约数中最大的一个。求最大公因数是数学和计算机科学中的常见问题,以下是几种常见的求法及其C语言实现。


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

辗转相除法是求最大公因数的经典算法,基于以下原理:

  • 如果(a > b),则(gcd(a, b)=gcd(b, a%b))。
  • 当(b = 0)时,(a)就是最大公因数。

C语言实现

#include <stdio.h>

// 辗转相除法
int gcd(int a, int b) {
    while (b!= 0) { // 当b不为0时循环
        int temp = b; // 临时变量保存b的值
        b = a % b;    // 更新b为a除以b的余数
        a = temp;     // 更新a为原来的b
    }
    return a; // 返回最大公因数
}

int main() {
    int a = 56, b = 98;
    printf("GCD of %d and %d is %d\n", a, b, gcd(a, b)); // 输出: GCD of 56 and 98 is 14
    return 0;
}

2. 更相减损法

更相减损法是中国古代的一种求最大公因数的方法,基于以下原理:

  • 如果(a > b),则(gcd(a, b)=gcd(b, a - b))。
  • 当(a = b)时,(a)就是最大公因数。

C语言实现

#include <stdio.h>

// 更相减损法
int gcd(int a, int b) {
    while (a!= b) { // 当a不等于b时循环
        if (a > b) {
            a = a - b; // 如果a大于b,则a减去b
        } else {
            b = b - a; // 如果b大于a,则b减去a
        }
    }
    return a; // 返回最大公因数
}

int main() {
    int a = 56, b = 98;
    printf("GCD of %d and %d is %d\n", a, b, gcd(a, b)); // 输出: GCD of 56 and 98 is 14
    return 0;
}

3. 递归版本的辗转相除法

递归版本的辗转相除法是辗转相除法的另一种实现方式,代码更简洁。

C语言实现

#include <stdio.h>

// 递归版本的辗转相除法
int gcd(int a, int b) {
    if (b == 0) { // 递归终止条件
        return a;
    }
    return gcd(b, a % b); // 递归调用
}

int main() {
    int a = 56, b = 98;
    printf("GCD of %d and %d is %d\n", a, b, gcd(a, b)); // 输出: GCD of 56 and 98 is 14
    return 0;
}

4. 二进制算法(Stein算法)

二进制算法是一种优化的求最大公因数的方法,基于以下原理:

  • 如果(a)和(b)都是偶数,则(gcd(a, b)=2 * gcd(a/2, b/2))。
  • 如果(a)是偶数,(b)是奇数,则(gcd(a, b)=gcd(a/2, b))。
  • 如果(a)和(b)都是奇数,则(gcd(a, b)=gcd(|a - b|, min(a, b)))。

C语言实现

#include <stdio.h>

// 二进制算法(Stein算法)
int gcd(int a, int b) {
    if (a == 0) return b; // 如果a为0,返回b
    if (b == 0) return a; // 如果b为0,返回a
    if ((a & 1) == 0 && (b & 1) == 0) { // 如果a和b都是偶数
        return 2 * gcd(a >> 1, b >> 1); // 返回2 * gcd(a/2, b/2)
    } else if ((a & 1) == 0) { // 如果a是偶数
        return gcd(a >> 1, b); // 返回gcd(a/2, b)
    } else if ((b & 1) == 0) { // 如果b是偶数
        return gcd(a, b >> 1); // 返回gcd(a, b/2)
    } else { // 如果a和b都是奇数
        return gcd(abs(a - b), (a < b)? a : b); // 返回gcd(|a - b|, min(a, b))
    }
}

int main() {
    int a = 56, b = 98;
    printf("GCD of %d and %d is %d\n", a, b, gcd(a, b)); // 输出: GCD of 56 and 98 is 14
    return 0;
}

5. 穷举法

穷举法是一种简单直观的方法,通过遍历所有可能的因数来找到最大公因数。

C语言实现

#include <stdio.h>

// 穷举法
int gcd(int a, int b) {
    int result = 1; // 初始化结果为1
    int min = (a < b)? a : b; // 找到a和b中的较小值
    for (int i = 1; i <= min; i++) { // 遍历1到min的所有整数
        if (a % i == 0 && b % i == 0) { // 如果i是a和b的公约数
            result = i; // 更新结果
        }
    }
    return result; // 返回最大公因数
}

int main() {
    int a = 56, b = 98;
    printf("GCD of %d and %d is %d\n", a, b, gcd(a, b)); // 输出: GCD of 56 and 98 is 14
    return 0;
}

6. 扩展欧几里得算法

扩展欧几里得算法不仅可以求出最大公因数,还可以求出满足(ax + by = gcd(a, b))的整数(x)和(y)。

C语言实现

#include <stdio.h>

// 扩展欧几里得算法
int extended_gcd(int a, int b, int* x, int* y) {
    if (b == 0) { // 递归终止条件
        *x = 1;
        *y = 0;
        return a;
    }
    int x1, y1;
    int gcd = extended_gcd(b, a % b, &x1, &y1); // 递归调用
    *x = y1;
    *y = x1 - (a / b) * y1;
    return gcd;
}

int main() {
    int a = 56, b = 98;
    int x, y;
    int result = extended_gcd(a, b, &x, &y);
    printf("GCD of %d and %d is %d\n", a, b, result); // 输出: GCD of 56 and 98 is 14
    printf("Coefficients (x, y): (%d, %d)\n", x, y);  // 输出满足ax + by = gcd(a, b)的系数
    return 0;
}

对辗转相除法的证明

解答:

辗转相除法基于以下原理:对于两个整数(a)和(b)((a > b)),其最大公约数等于(b)和(a)除以(b)的余数(r)的最大公约数,即(\gcd(a, b)=\gcd(b, r)),其中(r = a\bmod b)。

证明过程:

  1. 设(d = \gcd(a, b))
    • 按最大公约数定义,(d)能整除(a)和(b),即(d\mid a)且(d\mid b)。
  2. 表达(a)和(b)的关系
    • 由除法算法,(a = bq + r)((q)为商,(r)为余数,(0\leq r < b))。
  3. 证明(d)也是(b)和(r)的公约数
    • 因(d\mid a)且(d\mid b),代入(a = bq + r),得(d\mid(bq + r))。
    • 因为(d\mid bq),所以(d\mid r),即(d)也是(b)和(r)的公约数。
  4. 证明(d)是(b)和(r)的最大公约数
    • 假设存在整数(d'),(d'=\gcd(b, r))且(d' > d)。
    • 因(d'\mid b)且(d'\mid r),代入(a = bq + r),得(d'\mid a)。
    • 这表明(d')也是(a)和(b)的公约数,且(d' > d),与(d=\gcd(a, b))定义矛盾。
    • 所以(d)是(b)和(r)的最大公约数。
  5. 结论
    • 综上,证明了(\gcd(a, b)=\gcd(b, r))。
    • 此过程可反复进行,直至余数为(0),此时非零余数就是(a)和(b)的最大公约数。

最终答案:

辗转相除法通过反复应用(\gcd(a, b)=\gcd(b, a\bmod b))的关系,能找到两个整数的最大公约数。其正确性由上述数学证明保证,确保算法有效准确。

(\boxed{\gcd(a, b)=\gcd(b, a\bmod b)})

最小公倍数=a*b/gcd(a,b)

总结

  • 辗转相除法:高效且常用,适用于大多数场景。
  • 更相减损法:简单但效率较低,适用于小规模数据。
  • 二进制算法:优化了辗转相除法,避免了取模运算。
  • 穷举法:简单直观,但效率最低,适用于教学或小规模数据。
  • 扩展欧几里得算法:不仅可以求最大公因数,还可以求解线性方程。

根据具体需求选择合适的算法!


http://www.kler.cn/a/570714.html

相关文章:

  • Windows环境下Maven的配置
  • Linux驱动开发之串口驱动移植
  • 【Elasticsearch】索引生命周期管理相关的操作(Index Lifecycle Actions)
  • Spark核心之06:知识点梳理
  • Self-Pro: A Self-Prompt and Tuning Framework for Graph Neural Networks
  • 力扣hot100——二分查找
  • 养老小程序方案详解居家养老小程序系统
  • BIO、NIO、AIO、Netty从简单理解到使用
  • 2.数据结构:1.Tire 字符串统计
  • 【蓝桥杯单片机】第十二届省赛
  • 构建私有化AI知识库:基于CentOS的Ollama + DeepSeek-R1 +ragflow 整合部署教程
  • Android framwork 详细开发指南
  • 【UCB CS 61B SP24】Lecture 19 20: Hashing Hashing II 学习笔记
  • 跳石子(贪心)
  • 电机堵转电流与加减速箱堵转电流的关系
  • C++:四大强制类型转换
  • Kafka底层结构
  • 【算法系列】基数排序
  • 【CSS—前端快速入门】CSS 选择器
  • 内网渗透信息收集linuxkali扫描ip段,收集脚本(web安全)