C语言求两个正整数的最大公约数示例代码

目录
  • 前言
  • 1.穷举法
  • 2.欧几里得算法(辗转相除法)
  • 3.递归方法
  • 附:相减法
  • 总结

前言

两个正整数的最大公约数(Greatest Common Divisor, GCD)是能够整除这两个整数的最大整数。两个正整数的最大公约数的求法有多种解答,本文就三种方法做详细介绍:穷举法、欧几里得算法(辗转相除法)、递归方法。

我们从一道问题来引入:编写计算最大公约数的函数Gcd(),在主函数中调用该函数计算并输出从键盘任意输入的最大公约数。

1.穷举法

根据最大公约数的定义,我们可以采用一种最简单的方法——穷举法来编写代码。由于a和b的最大公约数不可能比a和b中的较小者还大,否则一定不能整除它,因此,先找到a和b中的较小者t,然后从t开始逐次减1尝试每种可能,即检验t到1之间的所有整数,第一个满足公约数条件的t,就是a和b的最大公约数。据此我们可编写函数Gcd()如下:

//函数功能:计算a和b的最大公约数,输入负数时返回-1
int Gcd(int a, int b)
{
    int i, t;
    if (a <=0 || b <= 0)
        return -1;
    t = a < b ? a : b;
    for (i=t; i>0; i--)
    {
        if (a%i==0 && b%i==0)
            return i;
    }
    return 1;
}

这种方法简单暴力,思维量小,但效率较低,且当两个正整数都较大,且最大公约数为1时,循环的次数为较小数的值,可想而知所需时间会很长。

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

下面介绍一种求最大公约数较常用的办法:欧几里得算法(辗转相除法)。

忽略数学原理,我们有如下算法:对正整数a和b,连续进行求余运算,直到余数为0为止,此时非0的除数就是最大公约数。设 r=a mod b 表示a除以b的余数,若 r≠0 ,则将b作为新的a,r作为新的b,重复 a mod b 运算,直到 r=0 为止,此时b为所求的最大公约数。例如,50和15的最大公约数的求解过程可表示为:Gcd(50, 15)=Gcd(15, 5)=Gcd(5, 0)=5。

用这种算法可编写函数Gcd()如下:

//函数功能:计算a和b的最大公约数,输入负数时返回-1
int Gcd(int a, int b)
{
    int r;
    if (a <= 0 || b <= 0)
        return -1;
    do{
        r = a % b;
        a = b;
        b = r;
    } while (r != 0);
    return a;
}

我们也可以考虑使用递归实现如下:

//函数功能:计算a和b的最大公约数,输入负数时返回-1
int Gcd(int a, int b)
{
    if (a <= 0 || b <= 0)
        return -1;
    if (a % b == 0)
        return b;
    else
        return Gcd(b, a % b);
}

3.递归方法

对于最大公约数,还有3条性质:

性质1 如果 a>b,则a和b与a-b和b的最大公约数相同;

性质2 如果 b>a,则a和b与a和b-a的最大公约数相同;

性质3 如果 a=b,则a和b的最大公约数与a值和b值相同。

对正整数a和b,当 a>b 时,若a中含有与b相同的公约数,则a中去掉b后剩余的部分a-b中也应含有与b相同的公约数,对a-b和b计算公约数就相当于对a和b计算公约数。反复使用最大公约数的3条性质,直到a和b相等为止,这时,a或b就是它们的最大公约数。

这就是所谓的第三种方法:递归方法。虽然此法被称为递归方法,但只是思想方法运用了递归的方法,并不代表只能使用递归实现。我们同样可以通过非递归和递归两种手段编写函数Gcd()。非递归实现如下:

//函数功能:计算a和b的最大公约数,输入负数时返回-1
int Gcd(int a, int b)
{
    if (a <= 0 || b <= 0)
        return -1;
    while (a != b)
    {
        if (a > b)
            a = a - b;
        else if (b > a)
            b = b - a;
    }
    return a;
}

编写递归函数如下:

//函数功能:计算a和b的最大公约数,输入负数时返回-1
int Gcd(int a, int b)
{
    if (a <= 0 || b <= 0)
        return -1;
    if (a == b)
        return a;
    else if (a > b)
        return Gcd(a-b, b);
    else
        return Gcd(a, b-a);
}

以上就是三种计算最大公约数的算法,可使用如下主函数来调用函数Gcd(),计算最大公约数:

#include <stdio.h>
int Gcd(int a, int b);
int main(void)
{
    int a, b, c;
    printf("Input a,b:");
    scanf("%d,%d", &a, &b);
    c = Gcd(a,b);
    if (c != -1)
        printf("Greatest Common Divisor of %d and %d is %d\n", a, b, c);
    else
        printf("Input number should be positive!\n");
    return 0;
}

求两个正整数的最大公约数的过程,实质上是使用最大公约数的定义及性质求解的过程,对此感兴趣的伙伴们可以自己研究相关数学原理与证明。

附:相减法

这种方法比较易于理解,原理是先判断两个正整数大小,并将较大数与较小数的差值赋给较大数,循环此步骤直到两数相等,此时得出最大公约数。

代码如下:

#include<stdio.h>

int main()

{

	int m,n;

	printf("请输入两个正整数:");

	scanf("%d %d",&m,&n);

	printf("%d%和%d的最大公约数是",m,n);

    while(m!=n)

	{

		if(m>n)

		{

			m=m-n;

		}else

		{

			n=n-m;

		}	

	}

	printf("%d",n);

	return 0;

} 

参考文献:

苏小红 王甜甜 赵玲玲 范江波 车万翔 等编著 王宇颖 主审,C语言程序设计学习指导(第4版),高等教育出版社,P57-60.

总结

到此这篇关于C语言求两个正整数的最大公约数的文章就介绍到这了,更多相关C语言两正整数最大公约数内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 详解C语言求两个数的最大公约数及最小公倍数的方法

    求两个正整数的最大公约数  思路:这是一个很基本的问题,最常见的就是两种方法,辗转相除法和辗转相减法.通式分别为 f(x, y) = f(y, x%y), f(x, y) = f(y, x - y) (x >=y > 0).根据通式写出算法不难,这里就不给出了.这里给出<编程之美>上的算法,主要是为了减少迭代的次数.      对于x和y,如果y = k * y1, x= k * x1,那么f(x, y) = k * f(x1, y1).另外,如果x = p * x1,假设p为素数

  • C语言项目全正整数后再计算的三种参考解答方法

    [项目-全正整数后再计算] 输入3个正整数,其中任一数不是正整数,程序输出Invalid number!,然后结束运行.当第1个数为奇数时,计算后两数之和,当第1个数为偶数时,计算第2数减去第3数的差.无论哪种情形,当结果超过10时按如下示例输出,否则什么也不输出. 示例 1: Enter number 1: 2 Enter number 2: -7 Invalid number! 示例2: Enter number 1: 17 Enter number 2: 3 Enter number 3:

  • C语言最大公约数示例教程

    目录 穷举法  辗转相除法  辗转相减法 穷举法 (1) i= a ,b中较小的数 (2)若a,b能同时被i整除,则i即为最大公约数,结束 (3)若不能,则 i--,再回去执行(2) #include<stdio.h> int main() { int i = 0; int j = 0; scanf("%d %d", &i, &j); int k = i > j ? i : j;//i>j,k=i;i<j,k=j while(1) { if

  • C语言辗转相除法求2个数的最小公约数

    辗转相除法最大的用途就是用来求两个数的最大公约数. 用(a,b)来表示a和b的最大公约数. 有定理: 已知a,b,c为正整数,若a除以b余c,则(a,b)=(b,c). (证明过程请参考其它资料) 例:求 15750 与27216的最大公约数. 解: ∵27216=15750×1+11466 ∴(15750,27216)=(15750,11466) ∵15750=11466×1+4284  ∴(15750,11466)=(11466,4284) ∵11466=4284×2+2898  ∴(114

  • C语言求两个正整数的最大公约数示例代码

    目录 前言 1.穷举法 2.欧几里得算法(辗转相除法) 3.递归方法 附:相减法 总结 前言 两个正整数的最大公约数(Greatest Common Divisor, GCD)是能够整除这两个整数的最大整数.两个正整数的最大公约数的求法有多种解答,本文就三种方法做详细介绍:穷举法.欧几里得算法(辗转相除法).递归方法. 我们从一道问题来引入:编写计算最大公约数的函数Gcd(),在主函数中调用该函数计算并输出从键盘任意输入的最大公约数. 1.穷举法 根据最大公约数的定义,我们可以采用一种最简单的方

  • Java求两个正整数的最大公约数和最小公倍数

    题目:输入两个正整数m和n,求其最大公约数和最小公倍数. 程序分析:利用辗除法. 最大公约数: public class CommonDivisor{ public static void main(String args[]) { commonDivisor(24,32); } static int commonDivisor(int M, int N) { if(N<0||M<0) { System.out.println("ERROR!"); return -1; }

  • C语言求两个字符串的最长公共子串

    本文实例讲述了C语言求两个字符串的最长公共子串的方法.分享给大家供大家参考.具体实现方法如下: #include "stdio.h" #include "string.h" #include "stdlib.h" void getCommon(char str1[],char str2[],char * str3); int stringLength(char * str); void main(){ char str1[50]; char st

  • c语言求两个字符串的交集

    目录 一.main()函数 二.fun1()函数 三.fun2()函数 注意; 总结 求两个字符串的交集,看似简单,实则需要考虑的细节很多. 我的思路: 1.将两个字符串简化,将里面重复的字母减少为一个. 2.拼接两个字符串,借助循环把重复出现两次的字符找出来. 有了思路开始写代码. 一.main()函数 思路: 1.定义两个储存字符串的数组tt[M],pp[M] 2.定义指针*p接收fun2() 返回值,输出交集 3.输入两个字符串(此处注意越界问题) 4.调用函数 5.输出交集 #inclu

  • C语言实现可保存的动态通讯录的示例代码

    目录 一.Contact.h 二.Contact.c 1.判断是否增容 2.初始化通讯录 3.打印 4.增加联系人信息 5.通过名字查找 6.删除联系人信息 7.查找信息 8.修改信息 9.排序 10.清空通讯录 11.保存通讯录为文件 三.text.c 四.错误写法分享 五.动图展示 一.Contact.h #pragma once #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <assert.h> #

  • C语言实现手写Map(全功能)的示例代码

    目录 为啥需要Map结构 主流Map结构 数组+链表的Map 结构 hash函数 创建Map集合 扩容基数 扩容Map集合 给Map集合添加元素 打印Map集合 获取Map集合中的指定元素 判断键是否存在 判断值是否存在 删除Map集合中的指定元素 修改Map集合中的指定元素 迭代器 获取所有的key 获取所有的value 复制一个Map 将一个map集合合并到另一个map集合里 合并两个Map集合,返回一个新的Map集合 差集 交集 补集 并集 清除Map 为啥需要Map结构 假设,数据很少,

  • C语言实现手写字符串处理工具的示例代码

    目录 头文件 实现文件 头文件 #ifndef STUDY_STR_UTIL_H #define STUDY_STR_UTIL_H #include "../structure/charhashmap.h" #include "../structure/charlist.h" #include "../structure/json.h" #include <malloc.h> #include <stdio.h> #inc

  • Android 同时setTag两次保存多种值的示例代码

    setTag是android的view类中很有用的一个方法,可以用它来给空间附加一些信息,在很多场合下都得到妙用. 示例代码: view.setTag(R.string.action_settings,hodler.content); 接收两个值,一个是key值,必须是唯一值,而且要写在values/string.xml 里面,例如 <resources> <item type ="id" name = "ffffff"></item&

  • vue实现两列水平时间轴的示例代码

    目录 一.实现组件timelineH.vue 二.调用组件 本文主要介绍了vue实现两列水平时间轴的示例代码,分享给大家,具体如下: 先上图,主要实现两列水平时间轴,查看了很多人实现的,水平只有一列,并且elementUI的时间轴只有竖着的,不支持横向,最后只能含泪自己实现了,没想到还可以,只是如果数据很多翻页还没实现,有实现过这种的掘友可以艾特我一下. 一.实现组件timelineH.vue timelineH.vue中的H代表横,起名字烦恼,哈哈. <template> <ul cl

随机推荐