如何消除2个数字的公因数

时间:2019-01-18 13:01:14

标签: c++

所以我有一个函数,可以将一对数字除,直到它们不再具有任何共同的因数:

void simplify(int &x, int &y){
    for (int i = 2;;++i){
        if (x < i && y < i){
            return;
        }
        while (1){
            if (!(x % i) && !(y % i)){
                x /= i;
                y /= i;
            } else {
                break;
            }
        }
    }
}

如何提高效率?我知道此解决方案中的一个问题是,它会测试复数的可除性,当它到达时没有任何因素时,这只是在浪费计算。我可以在程序不事先知道一组素数/在函数运行时对其进行计算的情况下执行此操作吗?

2 个答案:

答案 0 :(得分:4)

使用the Euclidean algorithm 1

  1. a 在两个给定的正整数中较大,而 b 较小。
  2. r a 的余数除以 b
  3. 如果 r 为零,我们就完成了,而 b 是最大公约数。
  4. 否则,让 a 取值为 b ,让 b 取值为 r ,然后转到步骤2。

一旦拥有最大的公约数,就可以将原始的两个数除以它,这将产生两个比率相同但没有任何公因子大于1的数。

引文

1 欧几里得,元素,书VII,命题1和2,大约公元前300年。

注释

Euclid使用了减法,此处已更改为余数。

一旦该算法开始工作,您可能会考虑稍微复杂一点的Binary GCD,它用减法和位运算代替除法(在某些处理器上比较慢)。

答案 1 :(得分:2)

听起来像C ++ 17库功能gcd的工作。

#include <numeric>
void simplify(int &x, int &y)
{
    const auto d = std::gcd(x, y);
    x /= d;
    y /= d;
}

Compiler Explorer