C++ iterator

m._.jooong·2023년 4월 25일
0

C++

목록 보기
17/23

#include <iostream>

// 문자열 라이브러리
#include <string>
// 스마트 포인터 라이브러리
#include <memory>
// 벡터 컨테이너 라이브러리
#include <vector>
// 리스트 컨테이너 라이브러리
#include <list>
// 배열 사이즈를 가져오는 라이브러리
#include <array>
// 랜덤 라이브러리
#include <time.h>

// C++ 표준 라이브러리
using namespace std;

int main()
{
    // 반복자(Iterator)
    // C++에서는 반복자를 지원하는데 , 이를 사용하면 컨테이너에 저장된 요소를 순회하고
    // 접근하여 효율적으로 컨테이너에 접근할 수 있다
    // 반복자는 포인터는 아니지만 비슷한 개념으로 볼 수 있다
    // 반복자를 이용하면 특정 컨테이너에 종속적이지 않게 컨테이너에 접근 가능하다

    // int타입을 여러개 저장할 수 있는 벡터컨테이너 타입의 intVector1 이름의
    // vector컨테이너 변수 선언
    vector<int> intVector1;

    for (int i = 0; i < 6; i++)
    {
        // 0 , 10, 20, 30, 40, 50
        intVector1.push_back(i * 10);
    }

    for (int i : intVector1)
    {
        cout << i << " ";
    }
    cout << endl;
    cout << endl;

    // 1. 반복자 선언
    // vector컨테이너 반복자인 iter반복자 선언
    vector<int>::iterator iter;

    // 2. 반복자 초기화
    // 반복자의 초기화는 중요하다. 
    // 초기화를 하지 않으면 계속 증가해서 에러가 날 수 있다

    // iter반복자는 intVector1의 시작점을 가리킨다
    iter = intVector1.begin();

    // 반복자는 포인터와 유사하지만 아니다
    // 반복자가 가리키는 값을 가져오기 위해서 *(역참조 연산자)를 사용한다
    //cout << "iter Value : " << *iter << ", iter address : "<< iter << endl;       // x
    cout << "iter value : " << *iter << ", iter address : " << &iter << endl;     // x
    cout << "iter value : " << *iter << ", iter address : " << &*iter << endl;

    cout << endl;
    cout << endl;

    // 프로그래밍 언어의 시작은 0부터 시작
    // 0번쨰 인덱스, 1번쨰 인덱, 2번쨰 인덱스, ... 5번쨰 인덱스 
    // 반복자는 인덱스가 아니다
    // 1번쨰 반복자, 2번쨰 반복자, ... 5번째 반복자

    int intArr1[] = { 0,1,2,3,4 };

    // 3. 반복자는 임의 접근이 가능하다
    // 하지만 주의할 점, 임의 접근은 인덱스를 통해 접근해서 해당 값을 반환한다
    // 하지만 iter반복자가 가리키는 값을 변경하는 것은 아니다
    cout << "iter[1] : " << iter[1] << endl;
    cout << "iter[3] : " << iter[3] << endl;
    cout << endl;
    cout << endl;

    // iter 반복자의 *(역참조 연산자)를 사용하면 2번째 인덱스 3번째 반복자의 요소값이 반환된다
    // iter = intVector1.begin() : intVector1의 인덱스 1번째 반복자를 의미한다
    // iter = intVector1.begin() +2 : intVector1의 2번째 인덱스 3번째 반복자를 의미한다
    iter = intVector1.begin() + 2;
    cout << "intVector1.begin() + 2 : " << *iter << endl;
    cout << endl;

    // iter = intVector1.begin() + 4; intVector1의 4번째 인덱스 5번째 반복자를 의미한다
    iter = intVector1.begin() + 4;
    cout << "intVector1.begin() + 4 : " << *iter << endl;
    cout << endl;

    // 4. += 연산자 사용 가능
    // 반복자를 초기화 하지 않으면 에러가 발생
    iter = intVector1.begin();      // 초기화를 하지않으면 7번째 인덱스 8번째 반복자를 의미한다
    iter += 3;      // 3번째 인덱스 4번째 반복자 반환
    cout << "iter : " << *iter << ", iter address : "<< &*iter << endl;
    cout << endl;
    cout << endl;

    /* 5. for문으로 컨테이너의 요소들을 출력하기*/
    cout << "for문 : " << endl;
    /* 첫번째 반복자*/
    vector<int>::iterator iter_begin = intVector1.begin();
    // 마지막 반복자의 다음 반복자이다
    vector<int>::iterator iter_end = intVector1.end();
    /*
    iter = iter_begin; : 초기값이다. 첫번째 반복자의 위치
    iter != iter_end; : 조건문이다. 만일 반복자가 마지막 반복자의 다음 위치가 아닐때까지
    */

    for (iter = iter_begin; iter != iter_end; iter++)
    {
        cout << "iter : " << *iter << ", iter address :" << &*iter << endl;
    }
    cout << endl;
    cout << endl;

    /* 6. while문*/
    cout << "while 문 : " << endl;
    // 반복자는 꼭 초기화 해야한다. 하지 않으면 에러가 발생
    iter = intVector1.begin();
    // 반복자가 마지막 반복자의 다음 위치가 아닐 때까지 반복한다
    while (iter != intVector1.end())
    {
        cout << *iter << " ";

        // while반복문을 빠져 나갈 수 있는 조건을 만들어야 한다.
        // 그렇지 않으면 무한 반복한다.

        // 후치 증가 연산자가 아니다. 
        // 연산자 오버로딩으로 반복자를 증가시켜 준다.
        iter++;
    }
    cout << endl;
    cout << endl;

    /* 7. foreach문*/
    cout << "foreach문 : " << endl;
    // foreach문은 반복자 없이도 컨테이너의 값을 출력할 수 있다.
    for (auto iter : intVector1)
    {
        cout << iter << " ";
    }
    cout << endl;
    cout << endl;

    /* foreach문의 다른 형태*/
    cout << "foreach문의 다른 형태 : " << endl;
    // & : 주소 연산자가 아니고 참조 연산자이다.
    for (auto& iter : intVector1)
    {
        cout << iter << " ";
    }
    cout << endl;
    cout << endl;

    /* 8. 반복자를 통한 요소 값 변경*/
    cout << "반복자를 통한 요소 값 변경 : " << endl;
    // 반복자를 사용할 때는 꼭 초기화를 해주어야 한다.
    iter = intVector1.begin();

    /**  포인터 연산자와 거의 유사하다*/
    *iter = 100;    // 첫번째 반복자에 100의 리터럴 값을 대입한다
    *(iter + 1) = 200;  // 두번째 반복자에 200의 리터럴 값을 대입한다.
    iter[2] = 300;  // 두번째 인덱스, 세번째 반복자에 300의 리터럴 값을 대입한다.

    for (iter = intVector1.begin(); iter != intVector1.end(); iter++)
    {
        cout << *iter << " ";
    }
    cout << endl;
    cout << endl;

    /** 9. intVector1[2] 앞에 15의 값을 추가한다*/
    cout << "intVector1[2] 앞에 15의 값을 추가한다." << endl;
    intVector1.insert(intVector1.begin() + 2, 15);

    for (iter = intVector1.begin(); iter != intVector1.end(); iter++)
    {
        cout << *iter << " ";
    }
    cout << endl;
    cout << endl;

    /** 10. intVector1[3] 제거하기*/
    cout << "intVector1[3] 제거 : " << endl;
    intVector1.erase(intVector1.begin() + 3);

    for (iter = intVector1.begin(); iter != intVector1.end(); iter++)
    {
        cout << *iter << " ";
    }
    cout << endl;
    cout << endl;

    /** 11. 반복문 안에서 erase()함수를 사용할 때는 주의해야 한다.*/
    //cout << "반복문 안에서 erase()함수를 사용할 때는 주의해야 한다." << endl;
    //vector<int> numbers{ 1,2,3,4,5,6,7,8,9,10 };

    //for (vector<int>::iterator it = numbers.begin(); it != numbers.end(); it++)
    //{
    //    // vector 컨테이너의 요소를 2로 나눈 나머지가 0이면 제거하기
    //    // 짝수 값에 제거해 주기
    //    if (*it % 2 == 0)
    //    {
    //        it = numbers.erase(it);
    //    }
    //}

    //for (int i : numbers)
    //{
    //    cout << i << " ";
    //}
    //cout << endl;
    //cout << endl;

    /** 12. 반복문 안에서 erase()함수를 사용할 때는 주의해야 한다.*/
    cout << "반복문 안에서 erase()함수를 사용할 때는 주의해야 한다." << endl;
    vector<int> numbers{ 1,2,3,4,5,6,7,8,9,10 };

    // 반복문안에서 erase() 함수가 호출되지 않았을 때만 it++ 를 해 준다,.
    for (vector<int>::iterator it = numbers.begin(); it != numbers.end();)
    {
        // vector컨테이너의 요소를 2로 나눈 나머지가 0이면 제거하기
        // 짝수 값을 제거
        if (*it % 2 == 0)
        {
            it = numbers.erase(it);
        }// 반복문 안에서 erase() 함수가 호출되지 않았을 때만 it++ 을 해 준다
        else
        {
            it++;
        }
    }

    for (int i : numbers)
    {
        cout << i << " ";
    }
    cout << endl;
    cout << endl;

    /** 13. 문자열을 여러개 저장할 수 있는 벡터 컨테이너에서 특정 문자열을 제거하기*/
    cout << "문자열을 여러개 저장할 수 있는 벡터 컨테이너에서 특정 문자열을 제거하기" << endl;

    vector<string>names{ "john", "James", "Tom", "Smith", "Jane" };

    // 반복문 안에서 이름에 "J" 문자열이 들어간 이름들을 지우기
    for (vector<string>::iterator name = names.begin(); name != names.end();)
    {
        // string::find() 함수는 찾는 단어나 문자열이 없으면 string::npos를 반환
        if ((*name).find("J") != string::npos)
        {
            name = names.erase(name);
        }   // 반복문 안에서 erase() 함수가 호출되지 않을 때만 name++ 해 주기
        else
        {
            name++;
        }
    }

    for (string name : names)
    {
        cout << name << " ";
    }

}

0개의 댓글