1

我正在尝试一个项目 euler 问题,第一个问题是它要求您计算 1000 以下的所有 3 和 5 的倍数之和。我尝试了它,它没有显示任何错误,但是当我运行它时,我收到一条消息错误框:

Microsoft Visual C++ Debug Library

Debug Assertion Failed!

Program: ...\c++ learning\project euler ex 1\Debug\project euler ex 1.exe
File: c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\vector
Line: 932

Expression: vector subscript out of range

For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.

(Press Retry to debug the application)

Abort   Retry   Ignore   

这是代码:

#include <iostream>
#include <vector>
#include <numeric>

using std::endl; using std::cout;
using std::vector;

int main()
{
vector<int> five;
vector<int> three;
int x;
int y;
int sum;

for(int i = 0; i < 1000; i = i + 5)
{
    five.push_back(i);
}

for(int i = 0; i < 1000; i = i + 3)
{
    three.push_back(i);
}



for(vector<int>::iterator it = five.begin(); it != five.end(); ++it)
{
    if (five[*it] % 3 == 0)
    {
        it = five.erase(it);
    }
}

for(vector<int>::iterator it = three.begin(); it != three.end(); ++it)
{
    if (three[*it] % 5 == 0)
    {
        it = three.erase(it);
    }
}

x = accumulate(five.begin(), five.end(), 0);
cout << x << endl;

y = accumulate(three.begin(), three.end(), 0);
cout << y << endl;

sum = x + y;
cout << sum << endl;
system("PAUSE");
return 0;
}

我知道有一种更简单的方法可以解决这个问题,但是我仍在学习 c++ 并想尝试使用我最近学到的一些东西。

4

2 回答 2

5

std::vector<T>::erase将在最后一个删除的元素之后返回一个迭代器。如果删除最后一个元素,则返回的迭代器将为end(). 然后你增加迭代器并得到一个异常。此外,即使您不删除最后一个条目而是另一个条目,您仍然会忽略以下元素。

顺便说一句,你想用什么来实现five[*it]?迭代器的作用类似于指向容器中给定元素的指针。要么使用带有int i and的简单 for 循环five[i](这将具有我上面提到的相同问题) *it. *

请尝试以下代码:

for(vector<int>::iterator it = five.begin(); it != five.end();)
{
    if (*it % 3 == 0)
    {
        it = five.erase(it);
    }
    else
         ++it;
}

* 虽然您的迭代器的值确实是它自己的键,但这只会持续到您第一次更改向量。所以在你第一次擦除之后five[*it] != *it

于 2012-08-04T15:52:43.373 回答
0

我认为您要实现的目标是由前两个for循环完成的。第一个循环将收集所有 3 的整数倍数,第二个循环将收集所有 5 的整数倍数。执行擦除的循环是多余的(在这些循环中,您使用erase循环中已经使用的迭代器存在问题)

于 2012-08-04T15:59:25.137 回答