【转】两个正整数的除法

编程实现两个正整数的除法,当然不能用除法操作符。

//编程实现两个正整数的除法,当然不能用除法操作符
int div(const int x, const int y)
{
    int left_num = x;
    int result = 0;
    int multi;
    while (left_num >= y)    //模拟小学学过的竖式除法运算
    {
        multi = 1;
        while (y * multi <= (left_num >> 1))
        {
            multi = multi << 1;
        }
        result += multi;
        left_num -= y * multi;
    }
    return result;
}

 

转载于:https://www.cnblogs.com/xmuliushuo/p/3355046.html

<think>嗯,用户问的是用Python实现两个正整数的最公约数的短除法。首先,我需要确认自己对短除法的理解是否正确。短除法,通常是指用这两个数公有的质因数连续去除,直到最后两个互质,然后把所有除数相乘得到最公约数。对吧? 那Python怎么实现呢?首先,得考虑如何找到这两个数的公有质因数。但可能短除法的具体步骤可能更倾向于逐步相除,而不是分解质因数。比如,先用最小的质数2去除,直到不能整除,再试3,依此类推。但这样的话,效率可能不高,尤其是对于数来说,找质因数比较麻烦。 不过,可能用户提到的短除法其实是更接近欧几里得算法的变种?或者是否另一种方法?需要明确短除法的具体步骤。例如,对于两个数a和b,从最小的质数开始试除,记录下所有能同时整除它们的质因数,然后把这些质因数相乘就是最公约数。例如,计算gcd(12, 18)的话,分解质因数的话,12=2²×3,18=2×3²,所以gcd是2×3=6。那么,短除法的过程可能就是将两数同时除以它们的公共质因数,直到互质,然后把除过的数相乘。 那么,如何在Python中实现这个过程?可能需要先找到两个数的公共质因数,然后依次除以这些因数,累积乘积。不过质因数分解本身对于数来说可能比较耗时,尤其是当数很时,这可能效率不如欧几里得算法。但用户明确问的是短除法,所以应该按照短除法的步骤来。 那具体的步骤应该是这样的: 1. 初始化一个变量result为1,用来保存公约数的乘积。 2. 从最小的质数2开始,检查是否能同时整除a和b。 3. 如果能整除,就将a和b都除以这个质数,result乘以这个质数,重复直到无法整除。 4. 然后尝试下一个质数3,重复步骤2-3。 5. 继续直到当前质数的平方于a和b中的较小的那个数。 6. 最后,如果剩下的a和b都于1,并且相等,那么result乘以这个数。 7. 返回result作为最公约数。 但这样实现起来可能需要先生成所有质数,或者逐个试除。例如,质数生成可能比较麻烦,或者可以简单地用试除法,每次尝试可能的因数,而不仅仅是质数,但这样可能会多试一些数。例如,当处理完2之后,下一个试3,然后5,7等,但中间可能有非质数的因数,但因为已经被前面的质因数除尽,所以后续的因数只能是质数? 或者,可能更简单的是,在每一步尝试从2开始的所有整数,而不仅仅是质数,但因为每次都会尽可能除尽,所以后续的非质因数可能已经被分解,所以实际上试除的因数都是质数? 比如,当处理完2之后,接下来试3,然后4,但此时4已经被分解成2的倍数,所以原来的数已经被除尽2的因数,所以4不可能再同时整除剩下的a和b,所以试除的顺序可以是2,3,4,5,6…但是这样可能效率不高。所以正确的做法应该是,在每一步试除的时候,用当前的除数i,从2开始,然后每次i递增,但可能更高效的做法是只试质数,但生成质数可能比较麻烦。 或许,在短除法的实际实现中,并不严格区分是否是质数,而是直接试除所有可能的整数,从2开始,直到无法继续为止。例如,当处理完2之后,继续用2尝试,直到无法整除,然后试3,同样重复直到无法整除,以此类推。但这样可能得到所有公共的因数,而不仅仅是质因数?或者,其实这样得到的是所有可能的公约数,包括合成的?例如,如果两个数都能被4整除,那么此时会被2连续除两次,从而累积两个2的因数。这时候,在短除法中,应该如何处理? 比如,假设a=24,b=36。他们的最公约数是12=2²×3。短除法的步骤是: - 用2除,两次,得到3和9。此时result=2×2=4。 - 然后用3除,得到1和3。result=4×3=12。 - 剩下的是1和3,互质,所以结束。最公约数是12。 那Python的实现过程应该是: 初始化result=1,i=2。 循环,i从2到可能的最因数: - 当i能同时整除a和b时,用i去除a和b,并将result乘以i,重复这个过程直到无法整除。 - 否则,i递增。 直到i超过a或b中的较小值。如果剩下的a和b都于1且相等的话,就乘上这个数。 比如,具体步骤: def gcd(a, b): result = 1 i = 2 while i <= a and i <= b: while a % i == 0 and b % i == 0: result *= i a = a // i b = b // i i += 1 if a == b and a > 1: result *= a return result 但这里可能有个问题,例如,当剩下的a和b是否相等?比如,假设a和b在最后变成12和18,经过处理i=2,i=3之后,可能剩下a=2, b=3,此时它们的公约数是1。所以在这种情况下,不需要乘剩下的数。但是如果剩下的a和b相等且于1的话,例如,比如初始数是15和25,在i=5的时候,除以5,得到3和5,此时i增加到6,超过较小的数3,此时剩下的a=3,b=5,不相等。而如果初始数是9和9,那么i循环到i=3时处理,得到a=3, b=3,再次处理i=3,得到a=1, b=1。此时result=9。但是如果是比如a=6和b=6,那么i=2的时候,除以2得到3和3,此时result=2。然后i增加到3,这时候进入循环,3可以整除3和3,所以除以3,得到1和1,result=6。这样就正确。 那上面的代码中,当i增加到超过较小的数的时候,比如当a和b经过多次除法后变成较小的数,比如当a=3,b=3时,i此时可能已经超过了3吗?比如,假设初始a=9, b=9。i从2开始,检查是否2能同时整除9和9?不能,所以i递增到3。此时,a=9,b=9。进入循环,在i=3时,每次除以3,直到得到a=1,b=1。这时候,i的下一次循环会继续增加,直到i>1,此时退出循环。然后检查如果a和b相等且于1吗?这里a和b都是1,所以不满足。所以返回result=9,正确。 另一个测试案例:比如a=12和b=18。初始result=1,i=2。第一次检查,12%2==0,18%2==0。于是进入循环,除以2,得到a=6,b=9,result=2。继续检查,i还是2,6%2==0,但9%2!=0。所以退出内层循环,i增加到3。此时检查a=6,b=9,i=3。6%3==0,9%3==0,进入内层循环。除以3,得到a=2,b=3,result=2*3=6。然后再次检查是否还能被3整除,此时2%3!=0,退出循环。i增加到4。此时i=4是否超过a和b中的较小值?此时a=2,b=3,i=4是否超过2?是的,所以循环结束。然后检查a和b是否相等?此时是2和3,不等。所以返回result=6。正确。 那么,这样的代码是否正确? 再考虑如果两个数互质的情况,例如a=5,b=7。代码中,i从2开始,检查到5是否被i整除?当i=2,3,4,5。当i=5时,此时i超过较小的数5?比如,当i增加到5时,循环条件是i<=5(因为此时a=5,b=7的较小值是5)。此时i=5,检查是否5能整除5和7?5整除5,但7除以5余2。所以不会进入内层循环。然后i增加到6,超过5,退出循环。然后检查a和b是否相等?5和7不等,所以返回result=1,正确。 那如果剩下的a和b相等的情况?比如a=6,b=6。经过处理后,变成a=1,b=1。此时i会增加到超过1,退出循环。然后检查是否相等,但a和b都是1,所以不处理,返回result=6。正确。 另一种情况,比如a=8,b=12。最公约数是4。代码的运行过程: i=2,第一次除以2,得到a=4,b=6,result=2。再次检查是否还能被2整除,可以,得到a=2,b=3,result=4。此时,i=2继续,但a=2,b=3,再次检查是否能被2整除,a可以,但b不行。所以退出内层循环,i增加到3。此时i=3,检查是否同时整除2和3,不能。i增加到4,此时i=4已经超过较小的数2,循环结束。然后检查a和b是否相等?不等。返回4,正确。 所以,这样的代码是正确的吗? 看起来是的。那么,这可能就是用户需要的Python实现的短除法。那这样,用户的问题就可以通过这个函数来解答。不过,需要注意的是,这可能不是最高效的方法,尤其是对于的数来说,因为需要逐个试除,而欧几里得算法的时间复杂度更低。但用户要的是短除法,所以必须按照这个步骤来。 那现在需要将这个思路化为步骤说明,并给出代码示例。需要确保代码正确,并且符合Python语法。比如,整数除法要用//,而不是/,否则会得到浮点数。 总结步骤: 1. 初始化结果变量为1。 2. 从最小的质数2开始,逐个尝试可能的因数。 3. 对于每个因数i,只要i能同时整除a和b,就将两数除以i,并累积到结果中。 4. 重复直到i超过两数中较小的那个。 5. 如果最终剩下的两数相等且于1,则乘到结果中。 6. 返回结果。 编写代码时,需要注意循环的条件和更新。比如,外层的while循环的条件是i<=a和i<=b,因为当i超过其中一个数时,就不可能同时整除了。而内层循环则是处理连续的因数,例如,当i=2时,可能连续多次除以2,直到无法整除为止。 最后,再测试几个例子,确保代码正确。</think>让我们分步骤介绍用短除法两个正整数公约数的Python实现: ### 步骤1:理解短除法原理 短除法核心思想:用两个数的公共质因数连续相除,直到余数互质,所有除数的乘积即为最公约数。 例如:gcd(12, 18) 1. 用公共因数2除 → 得6和9 2. 用公共因数3除 → 得2和3(互质) 3. 最公约数 = 2×3 = 6 ### 步骤2:Python实现逻辑 ```python def short_division_gcd(a, b): result = 1 i = 2 # 从最小质数开始尝试 while i <= a and i <= b: # 用i连续相除直到不能整除 while a % i == 0 and b % i == 0: result *= i a = a // i b = b // i i += 1 # 尝试下一个因数 # 处理最后相等的余数(如25和35最终余5和7的情况) if a == b and a > 1: result *= a return result ``` ### 步骤3:关键点解析 1. **双重循环结构**: - 外层循环:遍历所有可能的因数(从2开始) - 内层循环:处理连续重复的质因数(如处理2²的情况) 2. **终止条件**: - 当尝试的因数超过任意一个数时停止(`i > a or i > b`) 3. **特殊情况处理**: - 最后余数相等的情况(如gcd(15,15)=15) ### 步骤4:验证示例 ```python print(short_division_gcd(12, 18)) # 输出6 print(short_division_gcd(35, 14)) # 输出7 print(short_division_gcd(21, 22)) # 输出1(互质) ``` ### 步骤5:对比传统算法 - **优势**:直观体现质因数分解过程 - **劣势**:时间复杂度为$$O(n)$$,效率低于欧几里得算法($$O(\log n)$$) ### 最终代码 ```python def gcd(a, b): """使用短除法计算两个正整数的最公约数""" if a == 0 or b == 0: return max(a, b) # 处理含0的情况 result = 1 i = 2 while i <= a and i <= b: while a % i == 0 and b % i == 0: result *= i a //= i b //= i i += 1 if a == b and a > 1: result *= a return result ``` > 注意:这个实现包含对0的特殊处理,且严格遵循短除法的数学原理。对于需要高性能的场景,仍推荐使用欧几里得算法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值