Java 组合子和素因子分解:计算(m,n)的对数,其中GCD(m,n)=x

Java 组合子和素因子分解:计算(m,n)的对数,其中GCD(m,n)=x,java,algorithm,prime-factoring,greatest-common-divisor,Java,Algorithm,Prime Factoring,Greatest Common Divisor,计算(m,n)对的数量,其中GCD(m,n)=x,假设x=1和 1让我们从暴力算法开始: for (n = 1; n <= N; n++) { for (m = 1; m <= M; m++) { if (gcd(m, n) == x) count++; } } 在这些循环中,我们可以将所有数字除以x: for (n = x; n <= N; n += x) { for (m = x; m <= M; m += x) {

计算(m,n)对的数量,其中GCD(m,n)=x,假设x=1和
1让我们从暴力算法开始:

for (n = 1; n <= N; n++) {
    for (m = 1; m <= M; m++) {
        if (gcd(m, n) == x) count++;
    }
}
在这些循环中,我们可以将所有数字除以
x

for (n = x; n <= N; n += x) {
    for (m = x; m <= M; m += x) {
        if (gcd(m, n) == x) count++;
    }
}
int NN = N / x;
int MM = M / x;

for (n = 1; n <= NN; n++) {
    for (m = 1; m <= MM; m++) {
        if (gcd(m, n) == 1) count++;
    }
}

如果您的
M
N
超过100000,则需要相当长的时间才能运行。但是您可以轻松地将其并行化,因为(2,1)和(3,1)案例是独立的。

@M Oehm,这非常有效!但只适用于少数人。我确信它也可以用于100000这样的大数字,但当我在Java中复制它时,由于方法传播的重复递归,我得到了StackOverflowerError。我试图将其转换为迭代器,但不幸失败。你能帮我吗?只需要把递归方法转换成迭代方法。
#define NN (N / X)
#define MM (M / X)

void spread(int m, int n, int *count)
{
    if (n > NN) return;
    if (m > MM) return;

    if (n != m && m <= NN) (*count)++;
    (*count)++;

    spread(2*m - n, m, count);
    spread(2*m + n, m, count);
    spread(m + 2*n, n, count);
}

int main()
{
    int count = 1;

    spread(2, 1, &count);
    spread(3, 1, &count);

    printf("%d\n", count);

    return 0;
}
int spread(m, n)
{
    Queue q;
    int count = 1;

    q.push(m, n);

    while (!q.empty()) {
        int m, n;

        q.pull(&m, &n);

        if (n <= NN && m <= MM) {
            if (n != m && m <= NN) count++;
            count++;

            q.push(2*m - n, m);
            q.push(2*m + n, m);
            q.push(m + 2*n, n);
        }
    }

    return count;
}

int main()
{
    Queue q;
    int count = 1;

    count += spread(2, 1);
    count += spread(3, 1);

    printf("%d\n", count);

    return 0;
}