求任意数的最大公约数和公倍数

我看不太懂这个程序的答案😭

img

特别是公倍数p那里,它不用循环嘛?
如果要,它咋变化的诶
求问这个辗转相除法究竟怎么理解啊
真的超级无敌感谢大家了

这个最小公倍数不是这样求的吧

辗转相除就是两个数相除,得到商和余数,然后继续除,直到余数是0
这是个纯数学的问题,不理解不要紧,记住就行了,有兴趣可以搜一搜证明过程,为什么可以这样求解
至于最小公倍数,两个数相乘,再除以它们的最大公约数,不就是最小公倍数吗

  • 这有个类似的问题, 你可以参考下: https://ask.csdn.net/questions/7680297
  • 我还给你找了一篇非常好的博客,你可以看看是否有帮助,链接:编写一个函数,求两个整数的最大公约数,用 主函数调用这个函数并输出结果,两个整数由键盘 输入。(提示:用辗转相除法求最大公约数)
  • 除此之外, 这篇博客: 写一个算法交换单链表中p所指结点与其后继结点-21算法题中的 本题为算法题,交换的是结点,而不是结点的值 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
    • 注意题目是交换结点,不是交换结点的值。

    • 设q为1,p为2,r为3,r->next为4.原来为1234

    • 1指向3,2指向4,3指向2.最终顺序为1324

    • 结果如图所示,与交换了值的结果相同,但其本质上是交换了结点
      在这里插入图片描述

    代码如下

    #include <stdio.h>
    #include <stdlib.h>
    
    //定义结点结构
    typedef struct LNode
    {
        int data;
        struct LNode *next;
    }LNode,*LinkList;
    
    //初始化链表
    bool InitList(LinkList &L)
    {
        L=(LNode *)malloc(sizeof(LNode));
        if(L==NULL) return false;
        L->next=NULL; return true;
    }
    
    //尾插法建立链表
    LinkList list_TailInsert(LinkList &L)
    {
        InitList(L);
        int x;
        LNode *s,*r=L;
        
        while(scanf("%d",&x))
        {
            s=(LNode *)malloc(sizeof(LNode));//为新结点开辟空间,一定是在循环里面,每个新结点都要有新的空间
        
            if(x==-1) break;
            s->data=x;
            r->next=s;
            r=s;
        }
        r->next=NULL;
        return L;
    }
    //查找并返回第i个元素
    LNode *GetElem(LinkList L,int i)
    {
        if(i<=0) return NULL;
        LNode *p=L;
        for(int j=0;p!=NULL&&j<i;j++)
        {
            p=p->next;
        }
        return p;
    }
    
    //注意题目是交换结点,不是交换结点的值。
    //设q为1,p为2,r为3,r->next为4.原来为1234
    //1指向3,2指向4,3指向2.最终顺序为1324
    bool swap(LinkList &L,LNode *p)
    {
        if(p==NULL) return false;
        LNode *q=L,*r=p->next;//r为p的后继
        while(q->next!=p) q=q->next;//q为p的前驱
        q->next=r;//q的next指向p的后继
        p->next=r->next;//p的next指向r的后继
        r->next=p;//r的next指向p
        return true;
    }
    
    void PrintList(LinkList L)
    {
        LNode *p=L->next;
        for(;p!=NULL;p=p->next)
        {
            printf("%d\t",p->data);
        }
    }
    
    int main()
    {
        LinkList L;
        list_TailInsert(L);
        LNode *p=GetElem(L,6);
        swap(L,p);
        PrintList(L);
    }
    
  • 以下回答由chatgpt基于相关博客总结生成:

    问题解答

    首先,根据问题内容的描述,我们可以看到问题是关于辗转相除法和求最大公约数、公倍数的理解。

    辗转相除法的解释和理解

    辗转相除法,也称为欧几里德算法,是用于计算两个非零整数的最大公约数的一种方法。其基本思想是通过一系列的除法操作,将两个数逐渐缩小为除数和余数的关系,直到余数为零,此时的除数就是原始两个数的最大公约数。

    具体步骤为: 1. 将较大的数作为被除数,较小的数作为除数。 2. 用除数除以被除数,得到的余数为r。 3. 将除数更新为原始的被除数,被除数更新为r。 4. 重复执行步骤2和步骤3,直到余数为零。 5. 最后的被除数即为原始两个数的最大公约数。

    求最大公约数和公倍数的具体步骤

    根据辗转相除法,我们可以得到求两个数的最大公约数和公倍数的具体步骤。

    求最大公约数的步骤:

    1. 输入两个数a和b。
    2. 通过辗转相除法,计算出a和b的最大公约数gcd。
    3. 输出gcd作为两个数的最大公约数。

    求公倍数的步骤:

    1. 输入两个数a和b。
    2. 通过辗转相除法,计算出a和b的最大公约数gcd。
    3. 通过公式公倍数 = (a * b) / gcd,计算出两个数的公倍数。
    4. 输出公倍数作为两个数的公倍数。

    优化后的代码示例

    下面是一个优化后的代码示例,用于求任意两个数的最大公约数和公倍数:

    def gcd(a, b):
        """
        求两个数的最大公约数
        """
        while b:
            a, b = b, a % b
        return a
    
    def lcm(a, b):
        """
        求两个数的最小公倍数
        """
        return (a * b) // gcd(a, b)
    
    # 输入两个需要求最大公约数和最小公倍数的数
    a = int(input("请输入第一个数:"))
    b = int(input("请输入第二个数:"))
    
    # 调用函数计算最大公约数和最小公倍数
    max_gcd = gcd(a, b)
    min_lcm = lcm(a, b)
    
    # 输出结果
    print("{}{}的最大公约数为:{}".format(a, b, max_gcd))
    print("{}{}的最小公倍数为:{}".format(a, b, min_lcm))
    

    请注意,此示例代码是用Python编写的,如果使用其他编程语言,代码可能会有所不同。但是基本思路和步骤是相同的。这段代码首先定义了两个函数gcd和lcm,分别用于计算最大公约数和最小公倍数。然后通过输入两个数,调用这两个函数,计算出对应的结果,并输出最大公约数和最小公倍数。

    希望这个解答能帮到您,如果还有其他问题,请随时提问。

从程序中可以看出,最大公约数是用的辗转相除法,最小公倍数是用两数相乘除以最大公约数来算的。
辗转相除法:
假设要求15和10的最大公约数。
15÷10=1……5 (即较大数÷较小数)
10÷5=2……0 (即上一个算式的除数÷上一个算式的余数,一直按照这个方法算到余数为0,最大公约数就是那个算式的除数)
因此,15和10的最大公约数为5。

又如求49与91的最大公约数。
91÷49=1……42
49÷42=1……7
42÷7=6……0
所以49和91的最大公约数为7。

最小公倍数:
即较大数×较小数÷最大公约数
因此,15与10的最小公倍数为15×10÷5=30;
49与91的最小公倍数为49×91÷7=637。

原理解释完了,你再看看,能不能看懂。看不懂的话再问我

任何两个数的公因数求法:
例如两个数M,N 假设M〉N,他俩的最大公约数为q
二者可以写成
M=xq;
N=yq
因M=zN+r r表示余数 ,z表示商
所以xq=zyq+r ,因为q是M的最大公约数 必然 q也是r的约数
所以求M,N的最大公约数,也就是求 N,r的最大公约数
依次,求N,r 的最大公约数,就是求 N%r 和r的最大公约数,直至余数为0
最小公倍数,就是x
qyq/q =>xyq 只有这样,才可同时能整出于M,N,且最小