2012-08-04 75 views
1

我尝试的项目欧拉问题之一,第一个它要你计算的3所有倍数之和5低于1000 我尝试它,它没有显示出错误,但是当我运行它,我得到一个消息框出现错误:矢量标超出范围的错误消息的

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++,并想尝试使用我最近学习的一些东西吨。

+0

开始从最终循环的载体,而不是开始。 – user15 2012-08-04 15:51:25

+0

永远不要修改你迭代的集合。 – 2012-08-04 15:53:56

回答

4

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

顺便问一下,你想要什么,以实现与five[*it]?迭代器的作用类似于指向容器中给定元素的指针。既可以使用一个简单的for循环与int ifive[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

+0

只是注意到你是一个C++初学者。迭代器将充当智能指针。你几乎可以取消引用所有的迭代器并增加它们,独立于它们指向的实际内存(连续或不连续)。还要注意'push_back'是一个非常昂贵的方法。尝试首先使用调整大小或使用'std :: vector :: vector(size_t)'构造函数来分配矢量。另外,如果你想删除并添加许多元素,'dequeue'或'list'会更适合你。注意你不需要改变很多其他的东西,因为它们都提供迭代器。 – Zeta 2012-08-04 16:04:07

0

我想你想实现的是由两个第一for循环做了什么。第一个循环将收集所有整数倍数3和第二个整数倍数5。执行擦除的循环冗余(在这些循环位于中环已经使用迭代器使用erase您的问题)