有没有更有效的方法来计算强大的数字?

时间:2015-10-15 16:07:56

标签: c++ optimization

我正在尝试创建一个有效的函数来生成所有powerful numbers的向量,直到某些bound(最终我希望这个高达10 ^ 17或10 ^ 18,我认为它在64位无符号长long值的最大值范围内 - 2 ^ 64 - 1)。

我提出的最有效的方法发布在下面。我的问题是,是否有人有更好/更有效的建议。

当执行这个函数时,我有一个素数向量,直到同一个边界;我考虑过使用这个向量来计算强大的数字,但在撰写本文时我认为所显示的解决方案会更有效率。

std::vector<int> powerful(int bound){
    int x,y,cnt,num;
    std::vector<int>* pows =  new std::vector<ull>;
    for(int i = 4; i<bound;i++){
        x = i;
        y=3;
        cnt = 0;
        num = x;
        while(x%2==0){
            x/=2;
            cnt++;
        }
        while ((y <= x) && (cnt != 1)) {
            cnt = 0;
            while (x % y == 0) {
                x /= y;
                cnt++;
            }
            y += 2;
        }
        if(cnt>1)
            pows->push_back(num);
    }
    return *pows;
 }

3 个答案:

答案 0 :(得分:3)

这是一个递归+迭代解决方案,可以从其组成素数构建强大的数字:

#include <cstdlib>
#include <iostream>
#include <set>
#include <vector>

static const int bound = 1000;
static const std::vector<int> primes =
    // I'm assuming you can create this by Sieve of Eratosthenes or similar
    { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, };  // up to sqrt(bound)

typedef std::vector<int>::const_iterator prime_iter;

void add_powerful(std::set<int>& p, int v,
                  prime_iter it, prime_iter end, int bound)
{
    if (it == end) { // terminate the recursion
        p.insert(v);
        return;
    }

    add_powerful(p, v, it+1, end, bound);
    for (v *= *it * *it;  v <= bound;  v *= *it)
        add_powerful(p, v, it+1, end, bound);
}

int main()
{
    auto p = std::set<int>{};
    add_powerful(p, 1, primes.begin(), primes.end(), bound);
    for (auto i: p) std::cout << i << std::endl;
    return EXIT_SUCCESS;
}

add_powerful通过素数递归,在每种情况下乘以v乘以该素数的所有幂0,2,3,4,...(省略1)。

我的快速测试同意expected results高达1000。

答案 1 :(得分:1)

不是试图对一个数字进行反向工程以确定它是否是一个强大的数字,而是使用已知公式生成有力的数字:m = a^2 * b^3(来自您的链接)

您可以增加ab的值,以覆盖小于N的所有结果。

答案 2 :(得分:0)

在最小化操作次数方面,最有效的方法是通过其主要分解来生成所需的强大数字。优质分解是独一无二的,它们可以直接告诉您数字是否强大。给定一个小于或等于强大数字上界的平方根的素数列表,可以系统地生成所有不同的素数因子组合,从而产生一个范围内有力的数字。