有没有办法在C ++中分解大数

龙剑道

我编写了以下C ++代码来有效分解非常大的数字(数字高达24997300729)。我有一个包含约41000个素数的向量(我知道有这么大的向量虽然不是一个好主意,但无法解决这个问题)。该代码可立即生成中等数量的素数的质分解,但是当涉及到诸如24997300572之类的数字时,程序将停顿

这是下面的程序,带有一些输出截图:

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <cmath>

using namespace std;

vector<int> primes = {paste from  

   https://drive.google.com/file/d/1nGvtMMQSa9YIDkMW2jgEbJk67P7p54ft/view?usp=sharing
};

void factorize(int n) {
    if (n == 1)
        return;
    if (find(primes.begin(), primes.end(), n) != primes.end()) {
        cout << n <<" ";            //if n is prime dont'proceed further
        return;
    }

    //obtaining an iterator to the location of prime equal to or just greater than sqrt(n)
    auto s = sqrt(n);
    vector<int>::iterator it = lower_bound(primes.begin(), primes.end(), s);

    if (it == primes.end()) {
        return;                 // if no primes found then the factors are beyond range
    }
    for (auto i = it;i != primes.begin();i--) {
        if (n % *i == 0)
        {
            cout << *i << " ";
            n = n / (*i);
            factorize(n);
            return;             // the two consecutive for() loops should never run one after another
        }

    }
    for (auto i = it;i != primes.end();i++) {
        if (n % *i == 0)
        {
            cout << *i << " ";
            n = n / (*i);
            factorize(n);
            return;         // the two consecutive for() loops should never run one after another
        }
    }
}

int main() {
    unsigned int n;
    cout << "Enter a number between 1 and 24997300729 ";
    cin >> n;
    if (n > 24997300729) {
        cout << "Number out of range;";
        exit(-1);
    }
    factorize(n);
    return 0;
}

还行吧

还行吧

但这不是!!!

但这不是

我尝试使用它,long long intlong double在任何可以克服的地方都解决了这个问题,但这并没有太大帮助。

Any help Would Be Greatly Appreciated

Jerry Coffin

It's a little unclear (at least to me) exactly why you've structured the program the way you have.

You can fully factor a number by only looking for prime factors less than or equal to that number's square root. Any prime factor larger than those pairs with one prime factors smaller than that, so you only have to search for those to find all the prime factors. Any remaining factors can be obtained by simple division, not searching.

I'd probably generate the base of prime numbers on the fly (mostly likely using a sieve). The square root of 24'997'300'729 is (about) 158'105. A quick test shows that even without any work on optimization, a sieve of Eratosthenes will find the primes up to that limit in about 12 milliseconds.

Personally, I'd rather not have a fixed limit on the largest number the user can factor, other than the limit on the size of number we're working with, so if the user enters something close to the limit for a 64-bit number, we find all the primes that fit in 32 bits, and then use those to factor the number. This will obviously be slower than if we don't find as many primes, but a user probably won't be too surprised at the idea that factoring a larger number takes longer than factoring a smaller number.

So, implementing that, we might end up with code something like this:

#include <iostream>
#include <locale>
#include <vector>
#include <string>

using Number = unsigned long long;

auto build_base(Number limit) {
    std::vector<bool> sieve(limit / 2, true);

    for (Number i = 3; i < limit; i += 2) {
        if (sieve[i / 2]) {
            for (Number temp = i * i; temp < limit; temp += i)
                if (temp & 1)
                    sieve[temp / 2] = false;
        }
    }
    return sieve;
}

void factor(Number input, std::vector<bool> const &candidates)
{
    while (input % 2 == 0) {
        std::cout << 2 << "\t";
        input /= 2;
    }

    for (Number i = 1; i < candidates.size(); i++) {
        if (candidates[i]) {
            auto candidate = i * 2 + 1;
            while ((input % candidate) == 0) {
                    std::cout << candidate << "\t";
                    input /= candidate;
            }
        }
    }
    if (input != 1)
        std::cout << input;
}

int main(int argc, char **argv) {
    std::cout.imbue(std::locale(""));

    if (argc != 2) {
        std::cerr << "Usage: factor <number>\n";
        return EXIT_FAILURE;
    }

    auto number = std::stoull(argv[1]);
    auto limit = std::sqrt(number) + 1;
    auto candidates = build_base(limit);

    factor(number, candidates);
}

At a high level, the code works like this: we start by finding the primes up to the square root of the number the user entered. Since we want all the primes up to a limit, we use a sieve of Eratosthenes to find them. This builds a vector of bools, in which vector[n] will be true if n is prime, and false if n is composite. It does this starting from 3 (2 is a special case we kind of ignore for now) and crossing off the multiples of three. Then it finds the next number that hasn't been crossed off (which will be five, in this case), and crosses off its multiples. It continues doing that until it reaches the end of the array. To save some space, it leaves all the even numbers out of the array, because (other than that special case for 2) we already know none of them is prime.

一旦有了这些,我们就可以使用这些质数来找到要分解的数的质因数。这非常简单:遍历素数向量,并测试每个素数是否均分到目标数。如果是这样,请打印出来,将其除以目标编号,然后继续。

至少对我来说,这似乎相当可靠,并且速度相当快。如果我们想更好地分解较大的数字,那么下一步将是切换到分段筛。这可以极大地提高工作的第一部分的速度,例如,使我们(例如)可以在不超过约10秒的时间内分解出适合64位数字的任何内容。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

有没有办法将多态关联分解为模型?

来自分类Dev

Sympy:有没有办法收集和分解常数项

来自分类Dev

有没有办法知道Slurm中分配的节点何时可用?

来自分类Dev

有没有办法在循环的条件表达式中分配变量?

来自分类Dev

有没有办法将一列从两列中分离出来

来自分类Dev

有没有办法使用 DBSCAN 分配最大数量的集群?

来自分类Dev

有没有办法将这个 Unity 2d 代码分解成单独的方法

来自分类Dev

有没有办法跟踪Atlassian Crucible中分支的合并前和合并后代码审查

来自分类Dev

有没有办法跟踪Atlassian Crucible中分支的合并前和合并后代码审查

来自分类Dev

有没有办法让chrome-devtools(--inspect)自动从已经结束的进程中分离出来?

来自分类Dev

有没有办法限制Spring Batch作业中处理记录的最大数量?

来自分类Dev

有没有办法显示较大数字在较小数字范围内的位置?

来自分类Dev

有没有办法强迫amChart中的最大值小于最大数据值?

来自分类Dev

有没有办法在JavaScript中使用C ++?

来自分类Dev

有没有办法在没有名称空间的C ++中嵌套枚举?

来自分类Dev

有没有办法使用C#在autocad(.dwg)中获取所有折线?

来自分类Dev

有没有办法重构C#特有的switch语句?

来自分类Dev

有没有办法在 C++ 中并行循环遍历向量的所有元素?

来自分类Dev

有没有办法将C11编译为C89?

来自分类Dev

C / C ++:有没有办法原子地创建非零长度的文件?

来自分类Dev

有没有办法将函数从objective-c++传递给标准c++?

来自分类Dev

有没有办法比较lambda?

来自分类Dev

有没有办法缩短is / as构造?

来自分类常见问题

有没有办法在PHP中扩展特征?

来自分类Dev

有没有办法找出表之间的关系?

来自分类Dev

有没有办法让蟾蜍定期刷新数据

来自分类Dev

有没有办法缩短这个变量的定义?

来自分类Dev

有没有办法过滤Twilio呼叫日志?

来自分类Dev

有没有办法定义默认布局?

Related 相关文章

  1. 1

    有没有办法将多态关联分解为模型?

  2. 2

    Sympy:有没有办法收集和分解常数项

  3. 3

    有没有办法知道Slurm中分配的节点何时可用?

  4. 4

    有没有办法在循环的条件表达式中分配变量?

  5. 5

    有没有办法将一列从两列中分离出来

  6. 6

    有没有办法使用 DBSCAN 分配最大数量的集群?

  7. 7

    有没有办法将这个 Unity 2d 代码分解成单独的方法

  8. 8

    有没有办法跟踪Atlassian Crucible中分支的合并前和合并后代码审查

  9. 9

    有没有办法跟踪Atlassian Crucible中分支的合并前和合并后代码审查

  10. 10

    有没有办法让chrome-devtools(--inspect)自动从已经结束的进程中分离出来?

  11. 11

    有没有办法限制Spring Batch作业中处理记录的最大数量?

  12. 12

    有没有办法显示较大数字在较小数字范围内的位置?

  13. 13

    有没有办法强迫amChart中的最大值小于最大数据值?

  14. 14

    有没有办法在JavaScript中使用C ++?

  15. 15

    有没有办法在没有名称空间的C ++中嵌套枚举?

  16. 16

    有没有办法使用C#在autocad(.dwg)中获取所有折线?

  17. 17

    有没有办法重构C#特有的switch语句?

  18. 18

    有没有办法在 C++ 中并行循环遍历向量的所有元素?

  19. 19

    有没有办法将C11编译为C89?

  20. 20

    C / C ++:有没有办法原子地创建非零长度的文件?

  21. 21

    有没有办法将函数从objective-c++传递给标准c++?

  22. 22

    有没有办法比较lambda?

  23. 23

    有没有办法缩短is / as构造?

  24. 24

    有没有办法在PHP中扩展特征?

  25. 25

    有没有办法找出表之间的关系?

  26. 26

    有没有办法让蟾蜍定期刷新数据

  27. 27

    有没有办法缩短这个变量的定义?

  28. 28

    有没有办法过滤Twilio呼叫日志?

  29. 29

    有没有办法定义默认布局?

热门标签

归档