2012-08-04 3 views
1

저는 프로젝트 오일러 문제 중 하나를 시도했습니다. 첫 번째 문제는 1000 이하의 3과 5의 배수를 모두 계산하도록 요청한 것입니다. 시도했는데 아무 것도 표시하지 않습니다. 내가 그것을 실행할 때 오류가 그러나 나는 오류 메시지 상자를 얻을 : 그러나, 나는 그 문제를 할 수있는 더 쉬운 방법이 알고벡터 아래 첨자가 범위를 벗어났습니다. 오류 메시지

#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; 
} 

: 여기

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 

코드입니다 여전히 C++을 배우고 있으며 최근에 배웠던 것들 중 일부를 사용해보고 싶었습니다. 티.

+0

시작이 아니라 벡터의 끝에서 반복 시작합니다. – user15

+0

반복하는 컬렉션을 수정하지 마십시오. –

답변

4

std::vector<T>::erase은 마지막으로 제거 된 요소 다음에 반복자를 반환합니다. 마지막 요소를 제거하면 리턴 된 반복자는 end()이됩니다. 그리고 이터레이터를 증가시키고 예외를 얻습니다. 또한 마지막 항목을 삭제하지 않고 다른 항목을 삭제하더라도 다음 요소는 무시합니다.

그런데 five[*it]으로 무엇을 달성하고 싶습니까? 이터레이터는 컨테이너의 주어진 요소에 대한 포인터와 같은 역할을합니다. int ifive[i] (위와 동일한 문제가 있음)의 간단한 for-loop를 사용하십시오. 또는 . *

대신 다음 코드를 사용해보십시오 :

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'은 매우 값 비싼 메소드라는 점에 유의하십시오. resize 또는'std :: vector :: vector (size_t)'생성자를 사용하여 먼저 벡터를 할당 해보십시오. 또한 많은 요소를 삭제하고 추가하려면 'dequeue'또는 'list'가 더 적합 할 것입니다. 그것들은 모두 반복자를 제공하기 때문에 많은 다른 것들을 변경할 필요가 없다는 것에주의하십시오. – Zeta

0

내가 원하는 것은 두 개의 첫 번째 for 루프에 의해 수행됩니다. 첫 번째 루프는 3의 정수 배수를 모으고 두 번째 정수는 5의 배수의 정수를 모두 수집합니다. 지우개를 수행하는 루프는 중복됩니다 (이 루프에서는이 루프에서 이미 사용 된 반복자에서 erase을 사용하는 문제가 있습니다)

관련 문제