C++ 반복자(iterator)가 들어간 코드에서 이해가 안 가는 부분이 있습니다.(난이도: 초보자)


코드의 결과 :

이미지

질문 : iterator에 대한 개념이 부족하지만 좀 더 감을 익히고자 코드를 보면서 어떤식으로 쓰는지 공부하고 있습니다. 메인함수에서 마지막 for문 안에 있는 아래 부분의 코드가 잘 이해가 가질 않습니다.

제가 생각하기로는 .. if 절은 현재 반복자(Turtle ~ Frog 중..)의 위치가 시작점(Turtle)이면 winner = 현재 반복자(Turtle~ Frog 중..)가 가르키는 name을 get한다는 의미인 것 같고 else if 절은 현재 반복자의 location이 그 전 칸에 있는 반복자의 location보다 크면 그 반복자의 name을 get 하는 의미인 것 같습니다.

그런데 반복자의 위치가 첫칸인 begin에 있다고 하면 그거랑 location값이 가장 큰 거랑 무슨 상관이 있는건지 모르겠네요..

질문의 뜻이 좀 어려울 수 있겠네요 .. 대강.. 코드의 의미는 알 것 같은데 이게 왜 winner값을 구하게 되는 식인지를 모르겠다고 보시면 됩니다..

if (it == animal.begin())
    winner = (*it)->getName();
else if ((*it)->getLocation() > (*(it - 1))->getLocation()) 
    winner = (*it)->getName();

전체 코드 :

//헤더.h
#include <iostream>
#include <string>
using namespace std;

class Animal { // Animal class definition
protected:
    string name;
    int location;
    int* speed;
public:
    Animal(string, int, int*);
    int getLocation();
    string getName();
    void setLocation(int a);
    virtual void move()
    {
        cout << "General Animal class" << endl;
    }
};

class Turtle : public Animal { // Turtle class definition
public:
    Turtle(string);
    void move();
};

class Rabbit : public Animal { // Rabbit class definition
public:
    Rabbit(string);
    void move();
};

class Frog : public Animal { // Frog class definition
public:
    Frog(string);
    void move();
};
//헤더.cpp
#include "헤더.h"

int TTspeed[] = { 1,2,5 };
int rabspeed[] = { -1,0,1,2,10 };
int frogspeed[] = { 2,5 };

Animal::Animal(string name, int location, int *speed)
{
    this->name = name;
    this->location = location;
    this->speed = speed;
}

int Animal::getLocation()
{
    return location;
}

string Animal::getName()
{
    return name;
}

void Animal::setLocation(int location)
{
    this->location = location;
}

Turtle::Turtle(string name) : Animal(name, 0, TTspeed){}


void Turtle::move()
{
    int index = rand() % 3;
    location = location + speed[index];
    cout << "Turtle " << speed[index] << endl;
}

Rabbit::Rabbit(string name) : Animal(name, 0, rabspeed) {}

void Rabbit::move()
{
    int index = rand() % 5;
    location = location + speed[index];
    cout << "Rabbit " << speed[index] << endl;
}

Frog::Frog(string name) : Animal(name, 0, frogspeed) {}

void Frog::move()
{
    int index = rand() % 2;
    location = location + speed[index];
    cout << "Frog " << speed[index] << endl;
}
//소스.cpp
#include "헤더.h"
#include <vector>

void main() {
    Animal* n = new Turtle("Turtle");
    Animal* n1 = new Rabbit("Rabbit");
    Animal* n2 = new Frog("Frog");
    string winner;
    vector<Animal*> animal; // polymorphic list
    animal.push_back(n);
    animal.push_back(n1);
    animal.push_back(n2);
    vector<Animal*>::iterator it;
    for (int i = 0; i < 10; i++) {
        cout << "<-------round " << i+1 << "------>" << endl;
        for (it = animal.begin(); it != animal.end(); it++) {
            (*it)->move();
        }
    }
    cout << "==============================" << endl;

    for (it = animal.begin(); it != animal.end(); it++) {
        cout << (*it)->getName() << " " << (*it)->getLocation() << endl;
        if (it == animal.begin())
            winner = (*it)->getName();
        else if ((*it)->getLocation() > (*(it - 1))->getLocation()) 
            winner = (*it)->getName();
    }
    cout << "winner : " << winner << endl;
}
  • 2016년 10월 06일에 작성됨

조회수 112


1 답변


좋아요
1
싫어요
채택취소하기

이해하고 계신 내용이 맞는 것 같네요.

for (it = animal.begin(); it != animal.end(); it++) {
    cout << (*it)->getName() << " " << (*it)->getLocation() << endl;
    if (it == animal.begin())
        winner = (*it)->getName();
    else if ((*it)->getLocation() > (*(it - 1))->getLocation()) 
        winner = (*it)->getName();
}

위에서 먼저 다음 부분은

    if (it == animal.begin())
        winner = (*it)->getName();

어떤 자료가 우세한 것을 표현하려면, 최소한 2개가 필요합니다. 그런데 최초에 하나를 보는 경우에 (혹은 단 하나의 자료밖에 없는 경우)는 비교할 대상이 없습니다. 그래서 이 예에서는 최초의 한 개(혹은 단 하나만 존재하는 경우)는 그 것으로 우승자로 처리하는 방법을 선택한 것으로 보입니다.

그리고 다음부분입니다.

    else if ((*it)->getLocation() > (*(it - 1))->getLocation()) 
        winner = (*it)->getName();

아마도 Location은 달려간 거리같은 느낌인것 같네요. 같은 시점에 멀리 달려간 것이 우승일겁니다. 문맥상 가장 멀리간 동물이 우승인것으로 판별하는 프로그램으로 보입니다. 따라서 우승자를 선택하려면, 거리를 비교해야 하는 거겠지요?

그래서 지금 보고 있는 자료(it)와 이전에 봤던 자료(it-1)의 거리를 비교에서, 현재 보고 있는 자료가 이기고 있다면 winner를 변경하려는 내용인데, 여기에는 처음부터 현재이전(it-1)까지의 경쟁자들 중에서 winner가 선정되어 있다를 전제로 하고, 현재(it)가 이전을 이기면 최종 우승이다라는 생각으로 작성된 것 같습니다. (혹은 단순히 iterator 실습예일수도 있습니다.) 실제로 이부분에서 잘 안될 수도 있을 것 같네요.

위 예에서 Turtle이 Frog보다 값이 큰 경우가 문제가 됩니다. Turtle = 50 이고, Rabbit =19, Frog = 38인경우를 생각해보면 다음과 같이 될겁니다.

  1. 루프 1회에서 it는 Turtle이고, 혼자임으로 winner입니다.
  2. 루프 2회에서 it는 Rabbit이고, it-1인 Turtle보다 작으므로, winner를 변경하지 않습니다.
  3. 루프 3회에서 it는 Frog이고, it-1인 Turtle보다 큼으로, winner를 Frog로 변경합니다.

여기서 문제는 Rabbit에게 이긴 Turtle과 Frog중 누가 더 멀리갔는지 확인 없이 Frog를 winner로 선정한 것이 문제입니다.

의도한 것이 위의 내용이 맞다면 다음과 같이 바꾸는 것이 더 좋을 것 같습니다.

...
Animal *winner; // string winner에서 변경합니다.
...
// 마지막 반복문은 다음과 같이 winner를 참조하도록 변경해보세요.
for (it = animal.begin(); it != animal.end(); it++) {
    cout << (*it)->getName() << " " << (*it)->getLocation() << endl;
    if (it == animal.begin())
        winner = it;
    else if ((*it)->getLocation() > (*(winner))->getLocation()) 
        winner = it;
}
 cout << "winner : " << winner.getName() << endl;
  • 2016년 10월 08일에 작성됨
    리눅스(유닉스) 기반의 시스템에서 웹 서비스를 개발하고 있습니다.

  • 쉬운 설명 감사드립니다 ^^ 기존 코드의 문제는 winner를 정할때 it이 winner와 비교하는게 아니라 바로 전의 it-1 하고만 비교해서 문제가 되는 것이었군요..ㅎㅎ    이성우   2016.10.11 14:11     

로그인이 필요한 기능입니다.

Hashcode는 개발자들을 위한 무료 QnA사이트 입니다. 작성한 답변에 다른 개발자들이 댓글을 작성하거나 좋아요/싫어요를 할 수 있기 때문에 계정을 필요로 합니다.
► 로그인
► 계정만들기
Close