为什么这个找到具有 >500 个因子的最小三角形数的程序会崩溃?
Why does this program which finds the smallest triangle number with >500 factors crash?
我编写了下面的程序来解决欧拉计划 12,其中涉及找到具有超过 500 个因子的最小三角形数。
我认为没有大的错误。我怀疑内存优化可能是一个问题。然而,话虽如此,我需要 unsigned long long int 来表示最终将成为答案的大三角数。我从 triangleNumbers[0]=10,000,000,000 开始我的自然数序列。我知道 9,000,000,000 大约有 300 个因数,所以 10,000,000,000 是 "best guess."
然而,话虽这么说,我假设 10,000,000,000 是 "first natural number" 并继续添加后续自然数以获得 "second" 自然数及更多(因此 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
(没有这样的项目)。
Live Example using operator [ ]
Live Example showing what vector::at() does
请注意,第二个 link 表明您正在使用 at()
而不是 [ ]
访问第一个项目,从而越界访问元素。
要将项目添加到 std::vector
,请使用专门为此设计的方法之一,即 vector::push_back()
、vector::insert()
、vector::emplace_back()
、vector::resize()
, 或构造具有所需条目数的 std::vector
。
所有这些选项中最简单的是使用初始化列表构造向量:
std::vector<unsigned long long int> triangleNumbers =
{10000000000, 10000000002, 10000000005, 10000000009, 10000000014};
一旦你正确地设置了向量,那么你需要查看你的代码的其余部分,看看你可能在哪里访问了越界索引。尤其要查看循环中的 j
,以及如何将其用作索引。如果 j
超出范围,vector::at()
函数会立即告诉您。
编辑:如果您真的想要一种可以模拟 "auto-expanded" 数组的语法,最接近的方法是使用 this example 所见的 std::unordered_map<int, unsigned long long>
。
map
解决方案可能是一种直接替代品——您必须对其进行测试。
我编写了下面的程序来解决欧拉计划 12,其中涉及找到具有超过 500 个因子的最小三角形数。
我认为没有大的错误。我怀疑内存优化可能是一个问题。然而,话虽如此,我需要 unsigned long long int 来表示最终将成为答案的大三角数。我从 triangleNumbers[0]=10,000,000,000 开始我的自然数序列。我知道 9,000,000,000 大约有 300 个因数,所以 10,000,000,000 是 "best guess." 然而,话虽这么说,我假设 10,000,000,000 是 "first natural number" 并继续添加后续自然数以获得 "second" 自然数及更多(因此 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
(没有这样的项目)。
Live Example using operator [ ]
Live Example showing what vector::at() does
请注意,第二个 link 表明您正在使用 at()
而不是 [ ]
访问第一个项目,从而越界访问元素。
要将项目添加到 std::vector
,请使用专门为此设计的方法之一,即 vector::push_back()
、vector::insert()
、vector::emplace_back()
、vector::resize()
, 或构造具有所需条目数的 std::vector
。
所有这些选项中最简单的是使用初始化列表构造向量:
std::vector<unsigned long long int> triangleNumbers =
{10000000000, 10000000002, 10000000005, 10000000009, 10000000014};
一旦你正确地设置了向量,那么你需要查看你的代码的其余部分,看看你可能在哪里访问了越界索引。尤其要查看循环中的 j
,以及如何将其用作索引。如果 j
超出范围,vector::at()
函数会立即告诉您。
编辑:如果您真的想要一种可以模拟 "auto-expanded" 数组的语法,最接近的方法是使用 this example 所见的 std::unordered_map<int, unsigned long long>
。
map
解决方案可能是一种直接替代品——您必须对其进行测试。