2012-08-04 51 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您的問題)