c++ vector iterator에 관한 질문입니다!

greathero의 이미지

vector안에 문자열들이 저장되어 있구요.
저장된 문자열들을 하나하나 인출해서 새로운 newStr이라는 것을 만들어서 다시 해당 vector에 push_back을 하고 싶습니다.

그런데 아래 코드처럼 하니 vector iterator not incrementable이라는 에러 메시지가 뜨네요.
도무지 문제의 원인이 뭔질 몰라서 질문드립니다.

어떻게 하면 원하는대로 push_back을 할 수 있을까요?
꼭 도움 주시면 감사하겠습니다~^^

 
for(auto it = v->begin(); it != v->end(); ++it) { 
  string word = *it;
  for(int i = 0; i <= word.length(); ++i) {
    string newStr = word.substr(0, i) + firstChar + word.substr(i);
    v->push_back(newStr);
  }	
}
익명 사용자의 이미지

http://en.cppreference.com/w/cpp/container/vector/push_back

여길 보시면...

"If the new size() is greater than capacity() then all iterators and references (including the past-the-end iterator) are invalidated. Otherwise only the past-the-end iterator is invalidated."

v에 push_back 할 때마다 현재 capacity가 부족하기 때문에 새로운 메모리 영역을 할당해야 합니다.
이때 iterator가 무효화되어서 더이상 사용할 수 없고요.

문제를 해결하시려면 새로운 vector instance를 만들어서 거기에 push_back하거나, for loop 시작전에 미리 v의 capacity를 충분히 크게 잡아야 하겠습니다.

익명 사용자의 이미지

메모리 재할당이 매번 일어나지는 않을테니 push_back 할 때마다는 아니겠군요;;

greathero의 이미지

왜 안될까요...

jick의 이미지

벡터를 처음부터 "끝"까지 훑으면서 계속 같은 벡터에 뭘 넣고 있지 않습니까?
그러면 그 벡터의 "끝"은 어떻게 될까요?

* 잘 이해가 안가면 for loop 한바퀴 돌 때마다 벡터의 내용을 전부 출력해 보세요.

klara의 이미지

하고 싶으신게 무엇인가요? 계속 push_back하면 벡터가 점점 커지는데, 결국 이 코드가 의미하는 건 무한루프입니다. 이 코드가 제대로 돌던 안돌던 간에요.

greathero의 이미지

예를 들어서 "ABC"라는 문자열이 주어지면 ABC ACB BAC BCA CAB CBA와 같이 문자열로 구성할 수 있는 순열을 찾고 싶은데
그걸 재귀적으로 풀려다가 이렇게 꼬여버렸네요ㅠㅠ

void getPermutations(vector<string>* v, string str) { 
	if(str.length() <= 1) { 
		v->push_back(str);
		return;
	}
        // 맨 앞의 한 문자를 split하고 나머지 string들은 다시 재귀호출
        // 그러니깐 문자열 ABC에서 A를 SPLIT한 BC를 다시 재귀 호출
	char firstChar = str.at(0);
	getPermutations(v, str.substr(1));
 
        // 문제 있는 코드 -- 이걸 어떻게 바꿔야 될까요?
	for(auto it = v->begin(); it != v->end(); ++it) { 
		string word = (*it);
		cout << "word: " << word << endl;
		for(int i = 0; i <= word.length(); ++i) {
			string newStr = word.substr(0, i) + firstChar + word.substr(i);
			v->push_back(newStr);
		}	
	}
}
yhsuk의 이미지

STL은 잘 모르지만 테스트 해보니 돌아가서 올려봅니다. C++ 11에서 auto 키워드 의미가 달려졌군요~ 뭔가 했습니다

재귀호출 버전(코드는 효율적이진 않습니다)

void getPermutations(vector<string>* v, string str) {
    if(str.length() <= 1) {
        v->push_back(str);
        return;
    }
 
    // 맨 앞의 한 문자를 split하고 나머지 string들은 다시 재귀호출
    // 그러니깐 문자열 ABC에서 A를 SPLIT한 BC를 다시 재귀 호출
    for(int i = 0; i < str.length(); i++)
    {
        char firstChar = str.at(i);
        string newStr = firstChar + str.substr(0, i) + str.substr(i + 1);
 
        getPermutations(v, newStr.substr(1));
 
        for(auto it = v->begin(); it != v->end(); ++it) {
            if ((*it).length() == str.length() - 1) // 길이가 모자란 놈들만 하향 재귀호출했던 것들이므로
                (*it) = firstChar + (*it);
        }
    }
}

STL의 next_permutation 이용버젼

void getPermutations_v2(vector<string>* v, string str) {
    vector<char> v2;
 
    for(auto it = str.begin(); it != str.end(); ++it) {
        v2.push_back(*it);
    }
 
    do
    {
        string perm;
        for(auto it = v2.begin(); it != v2.end(); ++it) {
            perm += (*it);
        }
        v->push_back(perm);
    } while(std::next_permutation(v2.begin(), v2.end()));
}

Signature :) - "여유를 갖고 행동하되 게을러지지 말자"

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.