为什么这个找到具有 >500 个因子的最小三角形数的程序会崩溃?

Why does this program which finds the smallest triangle number with >500 factors crash?

本文关键字:三角形 小三 程序 崩溃 为什么 gt      更新时间:2023-10-16

我编写了下面的程序来解决欧拉项目12,该项目涉及找到超过500个因数的最小三角形数。

我认为没有什么大的错误。我怀疑内存优化可能是一个问题。话虽如此,但是,我需要unsigned long long int作为大三角形数的最终答案。我从triangleNumbers[0]=10,000,000,000开始我的自然数序列。我知道9,000,000,000大约有300个因数,所以10,000,000,000是"最好的猜测"。话虽如此,但是,我假设10,000,000,000是"第一个自然数",并继续添加后续的自然数以获得"第二个"自然数甚至更多(因此triangleNumbers[1]=10,000,000,000 + 2, triangleNumbers[2]=10,000,000,000 +3,以此类推)。

任何建议和提示将不胜感激。谢谢你帮助一个初学者进步。

#include <iostream>
#include <vector>
#include <math.h>
using namespace std;
bool keepRunning=true;
unsigned long long int naturalNumberCount=0;
unsigned long long int j=4;
unsigned long long int sum=0;
vector <unsigned long long int> triangleNumbers(0);
unsigned long long int totalFactors=0;
unsigned long long int trialDivisors=1;
unsigned long long int storer=0;
int main()
{
    triangleNumbers[0]=10000000000;
    triangleNumbers[1]=10000000002;
    triangleNumbers[2]=10000000005;
    triangleNumbers[3]=10000000009;
    triangleNumbers[4]=10000000014;
    //listed first few prime numbers above. j is set at 4 for this reason
    naturalNumberCount=5;
    //10000000014 is the 5th triangle number, and 5 is the 5th natural num
    //need this for recursive relation
    //5th triangle number = 4th triangle num + 5 (num + naturalNumberCount
    while(keepRunning)
    {
        for(trialDivisors;trialDivisors<=(unsigned long long int)(sqrt(triangleNumbers[j]));trialDivisors++)
        {
            if(triangleNumbers[j]%trialDivisors==0)
            {
                totalFactors++;
                if(totalFactors>499)//499 because the number itself will be a divisor of itself, so no need to check
                {
                    keepRunning=false;
                    break;
                }
                else
                {
                    keepRunning=true;
                }
            }
            else
            {
                keepRunning=true;
            }
        }
        //need the below to generate and store the next triangle number (as next element of array)
        naturalNumberCount++;//for recursive relation
        storer=triangleNumbers[j];//store the (j+1)'th triangle number, since we are changing j itself
        j++;//raise j, we gonna add the next value
        triangleNumbers[j]=(storer+naturalNumberCount);//the new value (last triangle number + current natural)
        totalFactors=0;//reset total factors to preclude any carry-over
    }

    cout<<triangleNumbers[j]<<flush;
    return 0;
}

TL;DR

#include <vector>
std::vector <unsigned long long int> triangleNumbers(0);
int main()
{
    triangleNumbers[0]=10000000000;
}

您有一个空向量,并且main中的第一行导致未定义行为,因为您试图访问项目0(没有这样的项目)。

使用操作符[]

的实例

显示vector::at()功能的实例

注意,第二个链接表明您使用at()而不是[ ]来访问第一个项目,从而访问了一个越界的元素。

要向std::vector中添加条目,请使用设计的方法之一,即vector::push_back(), vector::insert(), vector::emplace_back(), vector::resize(),或者用所需的条目数构建std::vector

在所有这些选项中,最简单的是使用初始化式列表构造vector:

std::vector<unsigned long long int> triangleNumbers = {10000000000, 10000000002, 10000000005, 10000000009, 10000000014};

std::向量参考

正确设置vector之后,您需要查看代码的其余部分,看看您可能在哪里访问了越界索引。特别是看看循环中的j,以及如何使用它作为索引。如果j越界,vector::at()函数会立即告诉你。


编辑:如果你真的想要一个语法来模拟一个"自动扩展"数组,最接近的方法是使用std::unordered_map<int, unsigned long long>,如本例所示。

可能map解决方案将是一个直接的替代品-您必须测试它。