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