求整数幂根

发布于 2024-12-23 03:46:59 字数 366 浏览 3 评论 0原文

查找数字的所有整数幂根的最佳(最有效)算法是什么?

也就是说,给定一个数字 n,我想找到 b(基数)和e< /code> (指数)使得

n = be

我想获取be所有可能的值对

Ps: n be正整数

What is the best (most efficient) algorithm for finding all integer power roots of a number?

That is, given a number n, I want to find b (base) and e (exponent) such that

n = be

I want to obtain all the possible value pairs of b and e

Ps: n b and e are to be positive integers .

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

本宫微胖 2024-12-30 03:47:00

首先求n的质因数分解:n = p1e1 p2 e2 p3e3 ...

然后求最大公约数g e1e2e3 ,...通过使用欧几里得算法

现在,对于 g 的任何因子 e,您可以使用:

b = p1e1/e p2e2/e p3e3/e ...

你有n = be

First find the prime factorization of n: n = p1e1 p2e2 p3e3 ...

Then find the greatest common divisor g of e1, e2, e3, ... by using the Euclidean algorithm.

Now for any factor e of g, you can use:

b = p1e1/e p2e2/e p3e3/e ...

And you have n = be.

梦年海沫深 2024-12-30 03:47:00

我认为蛮力方法应该有效:尝试从 2(1 是一个简单的解决方案)开始的所有 e,采用 r = n ^ 1/e,一个 双。如果r小于2,则停止。否则,计算 ceil(r)^efloor(r)^e,并将它们与 n 进行比较(您需要 ceilfloor 来补偿浮点表示中的错误)。假设您的整数适合 64 位,则无需尝试超过 64 个的 e 值。

下面是一个 C++ 示例:

#include <iostream>
#include <string>
#include <sstream>
#include <math.h>
typedef long long i64;
using namespace std;
int main(int argc, const char* argv[]) {
    if (argc == 0) return 0;
    stringstream ss(argv[1]);
    i64 n;
    ss >> n;
    cout << n << ", " << 1 << endl;
    for (int e = 2 ; ; e++) {
        double r = pow(n, 1.0 / e);
        if (r < 1.9) break;
        i64 c = ceil(r);
        i64 f = floor(r);
        i64 p1 = 1, p2 = 1;
        for (int i = 0 ; i != e ; i++, p1 *= c, p2 *= f);
        if (p1 == n) {
            cout << c << ", " << e << endl;
        } else if (p2 == n) {
            cout << f << ", " << e << endl;
        }
    }
    return 0;
}

当使用 65536 调用时,它会产生以下输出:

65536, 1
256, 2
16, 4
4, 8
2, 16

I think brute force approach should work: try all es from 2 (1 is a trivial solution) and up, taking r = n ^ 1/e, a double. If r is less than 2, stop. Otherwise, compute ceil(r)^e and floor(r)^e, and compare them to n (you need ceil and floor to compensate for errors in floating point representations). Assuming your integers fit in 64 bits, you would not need to try more than 64 values of e.

Here is an example in C++:

#include <iostream>
#include <string>
#include <sstream>
#include <math.h>
typedef long long i64;
using namespace std;
int main(int argc, const char* argv[]) {
    if (argc == 0) return 0;
    stringstream ss(argv[1]);
    i64 n;
    ss >> n;
    cout << n << ", " << 1 << endl;
    for (int e = 2 ; ; e++) {
        double r = pow(n, 1.0 / e);
        if (r < 1.9) break;
        i64 c = ceil(r);
        i64 f = floor(r);
        i64 p1 = 1, p2 = 1;
        for (int i = 0 ; i != e ; i++, p1 *= c, p2 *= f);
        if (p1 == n) {
            cout << c << ", " << e << endl;
        } else if (p2 == n) {
            cout << f << ", " << e << endl;
        }
    }
    return 0;
}

When invoked with 65536, it produces this output:

65536, 1
256, 2
16, 4
4, 8
2, 16
深者入戏 2024-12-30 03:47:00

混合 interjay 和 dasblinkenlight 的方法。首先找出n 素因数分解中的所有小素因数(如果有)及其指数。 “small”的适当值取决于 n,对于中等大小的 np <= 100 就足够了,对于 Large np <= 10000p <= 10^6 可能更合适。如果您找到任何小的质因数,您就知道e必须除以您找到的所有指数的最大公约数。通常,gcd 将为 1。无论如何,可能的指数范围将会减小,如果 n 没有小的质因数,您就知道 e e < ;= log(n)/log(small_limit),这是对 log(n)/log(2) 的一个很好的缩减,如果您找到了几个小的质因数,他们的gcd指数为gn的余数为m,只需检查g的除数即可不超过log(m)/log(small_limit)

Mix the approaches of interjay and dasblinkenlight. First find all small prime factors (if any) and their exponents in the prime factorisation of n. The appropriate value of 'small' depends on n, for medium sized n, p <= 100 can be sufficient, for large n, p <= 10000 or p <= 10^6 may be more appropriate. If you find any small prime factors, you know that e must divide the greatest common divisor of all exponents you found. Quite often, that gcd will be 1. Anyway, the range of possible exponents will be reduced, if n has no small prime factors, you know that e <= log(n)/log(small_limit), which is a good reduction from log(n)/log(2), if you have found a couple of small prime factors, the gcd of their exponents is g, and the remaining cofactor of n is m, you only need to check the divisors of g not exceeding log(m)/log(small_limit).

雨夜星沙 2024-12-30 03:47:00

我的方法是否适合您的需求取决于任务的规模。

首先,有一个明显的解决方案:e = 1,对吧?
从那时起,如果你想找到所有的解决方案:我能想到的所有算法都需要找到 n 的某个素因数。如果这只是一个独立的任务,那么没有什么比对素数进行暴力破解更好的了(如果我没记错的话)。找到第一个质因数 p 及其相应的指数(即满足 p^k / n 的最大数字 k)后,您只需检查 e 的 k 的约数。对于每个这样的指数 l (再次 l 迭代 k 的所有除数),您可以使用二分搜索来查看 n 的 l 次方根是否为整数(相当于找到新的解决方案)。

It depends on the dimensions of the task whether my approach will suite your needs.

First of all there is one obvious solution: e = 1, right?
From then on if you want to find all the solutions: all the algorithms I can think of require to find some prime factor of n. If this is just a single independent task nothing better than brute force on the primes can be done (if I am not wrong). After you find the first prime factor p and its corresponding exponent (i.e the highest number k such that p^k / n) you need to check for e only the divisors of k. For every such exponent l (again l iterates all divisors of k) you can use binary search to see if the lth root of n is integer (equivalent to finding new solution).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文