[코딩 테스트] 프로그래머스 C++ 코테 준비 필수 문법 | 빌트인 데이터 타입, STL

코딩 테스트 문제를 풀기 전에는 당연히 코딩 테스트에. 사용할 언어의 문법을 알아야 합니다. 여기서는 C++ 기초 문법을 충실히 설명하기보다는 코딩 테스트에 자주 사용하는 문법을 설명하는 데 집중합니다. C++ 기초서 1권을 완독했다는 가정하에 설명했으므로 참고하기 바랍니다.

1. 빌트인 데이터 타입

C++에서 많이 사용하는 빌트인 데이터 타입은 정수형(Int), 부동소수형(Float 혹은 Double), 논리형(Bool), 문자형(Char)이 있습니다. 그리고 같은 타입의 기본 자료형 변수들을 연속된 메모리에 저장할 수 있는 배열(Array)도 있습니다.

※ C++에서 빌트인 타입은 헤더 파일을 포함하지 않아도 사용할 수 있는 기본 내장 데이터 타입을 의미합니다.

1.1 정수형

정수형은 양의 정수, 음의 정수, 0을 포함합니다. 정수형은 더하기, 빼기, 곱하기, 나누기와 같은 사칙 연산을 수행할 수 있습니다. 이 책을 펼친 독자라면 대부분 설명 없이 코드만 봐도 쉽게 이해할 수 있을 것입니다. 코드 양이 많아서 좀 지루할 수도 있지만 연산자는 글보다는 코드를 보며 공부해야 훨씬 직관적이고 이해하기 쉬우니 꼭 살펴보기 바랍니다.

 

정수형 변수 선언 및 산술 연산

#include <iostream>

using namespace std;

int main() {
  int a = 13;
  int b = 4;
  cout << a + b << endl; // 더하기 / 17
  cout << a - b << endl; // 빼기 / 9
  cout << a * b << endl; // 곱하기 / 52
  cout << a / b << endl; // 나누기 / 3
  cout << a % b << endl; // 모듈러 연산 / 1
  cout << -a << endl; // 부호를 바꿈 / -13

  return 0;
}

 

정수형 비교 연산

#include <iostream>

using namespace std;

int main() {
  int a = 13;
  int b = 4;
  // 비교 연산이 참이면 1을, 거짓이면 0을 반환합니다.
  cout << (a == b) << endl; // 같은 값인지 비교 / 0
  cout << (a != b) << endl; // 같지 않은 값인지 비교 / 1
  cout << (a > b) << endl; // 왼쪽 값이 더 큰지 비교 / 1
  cout << (a < b) << endl; // 오른쪽 값이 더 큰지 비교 / 0
  cout << (a >= b) << endl; // 왼쪽 값이 더 크거나 같은지 비교 / 1
  cout << (a <= b) << endl; // 오른쪽 값이 더 크거나 같은지 비교 / 0

  return 0;
}

 

정수형 비트 연산

#include <iostream>

using namespace std;
  int main() {
  int a = 13;
  int b = 4;
  cout << (a & b) << endl; // AND 연산 / 4
  cout << (a | b) << endl; // OR 연산 / 13
  return 0;
}

 

AND 연산과 OR 연산을 알아보겠습니다. AND 연산은 직렬 연결이라고 생각하면 쉽습니다. 직렬 연결은 모든 스위치가 닫혀야 동작합니다. 따라서 다음 그림에서 첫 번째와 두 번째 스위치 모두 1인 case 4만 회로가 동작합니다. 각 case에서 0은 스위치가 열린 것, 1은 스위치가 닫힌 것을 의미합니다.

 

 

OR 연산은 병렬 연결이라고 생각하면 쉽습니다. 병렬 연결은 하나의 스위치라도 닫혀 있다면 동작합니다. 따라서 다음 그림에서 첫 번째와 두 번째 스위치 중 하나라도 1인 case 2, 3, 4에서 모두 회로가 동작합니다.

 

 

이제 AND와 OR의 개념을 이해했으니 실제 변수 동작을 봅시다. 다음 그림과 같이 각 변수를 2진수로 표현했을 때 각 순서에 맞는 비트 값끼리 연산을 수행합니다.

 

 

1.2 부동소수형

부동소수형은 소수를 저장할 때 사용합니다. 부동소수형도 연산 결과를 보며 설명하겠습니다.

 

부동소수형 사칙 연산

#include <iostream>

using namespace std;

int main() {
  double d = 2.5;
  float f = 1.5f;

  cout << sizeof(d) << endl; // double형 데이터의 크기(Byte) / 8
  cout << sizeof(f) << endl; // float형 데이터의 크기(Byte) / 4
  cout << d << " " << f << endl; // 2.5 1.5
  cout << d + f << endl; // 더하기 / 4
  cout << d - f << endl; // 빼기 / 1
  cout << d * f << endl; // 곱하기 / 3.75
  cout << d / f << endl; // 나누기 / 1.66667

  return 0;
}

 

C++에서 부동소수형은 float와 double이 있습니다. 이 둘의 다른 점은 유효한 소수점의 자릿수입니다. 코드 실행 결과를 보면 double은 8 바이트 float는 4 바이트이므로 double의 유효한 소수점의 자릿수가 더 많습니다. double은 15자리 float는 7자리로 보면 됩니다. 코딩 테스트에서는 이 정도의 정밀함을 요구하는 문제까지는 나오지 않으므로 둘 중 하나만 기억해도 공부하는데 크게 지장은 없습니다.

 

형변환

C++은 변수를 선언하는 순간 타입이 정해집니다. 따라서 구현을 하다가 타입을 변경해야 할 필요가 있으면 형 변환을 해야 합니다. 형 변환은 타입이 서로 다른 변수간 연산을 하여 발생하는 암시적 형 변환(Implicit Conversion)과 사용자가 임의로 변경하는 명시적 형 변환(Explicit Conversion)이 있습니다.

다음 예를 보면 쉽게 이해할 수 있습니다.

※ 보통 암시적 형 변환은 변수의 메모리 크기가 큰 쪽으로 타입을 변환합니다.

※ 예를 들어 크기가 정수형(4 바이트)과 부동소수형(8 바이트)를 연산하면 결과는 부동소수형입니다.

 

#include <iostream>

using namespace std;

int main() {
  int i = 65;
  float f = 5.2f;

  // 암시적 형 변환(메모리가 큰 float으로 변환됨)
  double d = i + f;
  cout << d << endl; // 70.2
  // 명시적 형 변환 double ➝ int
  cout << static_cast<int>(d) << endl; // 70
  // 명시적 형 변환 int ➝ char
  cout << static_cast<char>(i) << endl; // 'A'

  return 0;
}

 

1.3 문자열

C++에서는 문자열 자료형을 제공합니다. 문자열은 string 표준 헤더를 추가하여 사용할 수 있고, 문자열 작업을 쉽고 효율적으로 할 수 있는 다양한 메서드를 제공합니다.

 

문자열 선언 및 초기화

문자열을 초기화하는 방법은 여러 가지가 있습니다. 대입 연산자를 활용하는 방법을 많이 사용하고, 생성자로 다른 문자열을 복사하거나 특정 문자를 반복한 패턴의 문자열을 생성할 수도 있습니다. 아래 코드 예를 참고하면 바로 이해가 될 겁니다.

 

#include <iostream>
#include <string>

using namespace std;

int main() {
  string str1; // 빈 문자열 선언
  string str2 = "Hello, World!"; // 문자열 직접 초기화
  string str3(str2); // 문자열 복사
  string str4(str2, 0, 5); // 문자열 부분 복사 초기화 / "Hello"
  string str5(10, '*'); // 반복된 문자로 문자열 초기화 / "**********"

  return 0;
}

 

문자열 찾기

특정 문자나 문자열을 찾을 때는 find( ) 메서드를 사용합니다. find( ) 메서드는 다음과 같이 오버 로딩되어 있습니다.

  • find(찾으려는 문자열) // ①
  • find(찾으려는 문자열, 탐색 시작 위치) // ②

만약 처음부터 문자열을 찾는다면 ①을 이용하면 되고, 특정 위치부터 문자열을 찾는다면 ②를 사용하면 됩니다. find( ) 메서드는 문자열을 찾으면 해당 문자열이 시작하는 인덱스를 반환하고, 찾지 못하면 stirng::npos를 반환합니다. 그리고 탐색하는 문자열의 길이가 N일 때 find( ) 메서드는 O(N)으로 동작합니다.

 

#include <iostream>
#include <string>

using namespace std;

int main() {
  // 문자열 초기화
  string str = "Hello, C++ World!";

  // ② "Hello" 문자열 찾기
  size_t pos1 = str.find("Hello");
  cout << pos1 << endl; // 0

  // ③ 'C' 문자 찾기
  size_t pos2 = str.find('C');
  cout << pos2 << endl; // 7

  // ④ "Hello" 문자열 찾기, 시작 인덱스 지정
  size_t start_index = 2;
  size_t pos3 = str.find("Hello", start_index);
  cout << pos3 << endl; // ① 18446744073709551615

  // 존재하지 않는 문자열 찾기
  size_t pos4 = str.find("Python");
  cout << pos4 << endl; // ① 18446744073709551615

  return 0;
}

 

① 코드의 ‘18446744073709551615’라는 출력값이 string::npos 값이라고 보면 됩니다. 환경에 따라 값이 다를 수도 있습니다. ② size_t라는 타입도 보이는데요, 보통 컨테이너나 문자열의 크기 및 인덱스를 표현할 때 이 타입을 사용합니다.

③에서는 “C” 문자열의 시작 위치인 7을 반환합니다.

그리고 ②와 ④를 비교해봅시다. ②는 “Hello”를 찾아서 0을 반환했지만 ④에서는 문자열을 찾지 못해서 string::npos를 반환했습니다. 왜 그럴까요? find( ) 메서드의 탐색 시작 위치가 다르기 때문입니다. str.find(“Hello”)는 탐색 시작 위치가 0이므로 “Hello”를 찾았지만 str.find(“Hello”, 2)는 탐색 시작 위치가 2이므로 “Hello”를 찾지 못한 것입니다. 그림으로 나타내면 다음과 같습니다.

 

 

#include <iostream>
#include <string>

using namespace std;

int main() {
  string str = "APPLE";
  str += ", World!"; // ① 문자열 추가
  cout << str << endl; // "Apple, World!" 출력

  // 문자열 수정
  str[7] = 'P'; // ② 7번째 문자 W → P로 수정
  cout << str << endl; // "Apple, Porld!" 출력

  str.replace(7, 4, "Col"); // ③ 7번째 문자부터 'col'로 변경
  cout << str << endl; // "Apple, Cold!" 출력

  return 0;
}

 

위 코드의 동작을 그림으로 나타내면 다음과 같습니다. ① 기존 str에 “, World!”를 더하는 과정입니다.

 

 

특정 위치의 문자를 변경하고 이어서 replace( ) 메서드로 특정 범위 문자열을 변경하는 동작을 보겠습니다. ② [ ] 연산자로 7번째 문자의 값을 ‘W’에서 ‘P’로 변경했고, ③ replace( ) 메서드로 7번째 위치부터 4개의 문자열을 “Col”로 변경했습니다.

 

 

2. STL

STL(Standard Template Library)이란 C++에서 제공하는 템플릿 기반의 표준 라이브러리입니다. 템플릿을 처음 보는 분들을 위해 간단하게 설명하면, C++에서 함수나 클래스를 구현할 때 어떤 타입에서도 동작할 수 있도록 하는 문법입니다. 따라서 STL 역시 특정 타입에 한정하지 않고 라이브러리를 사용할 수 있습니다. STL은 크게 데이터를 담을 수 있는 컨테이너(Container), 데이터를 처리하고 제어할 수 있는 여러 가지 알고리즘(Algorithm), 컨테이너에 접근 및 순회할 수 있게 하는 반복자(Iterator)로 이루어져 있습니다.

 

2.1 STL과 자주 사용하는 필수 문법

다음 내용은 STL 문법은 아니지만 STL과 자주 사용하는 문법입니다.

 

상수 레퍼런스

C++에서는 함수의 인수로 값을 전달할 때 값을 복사합니다. 이를 call by value라고 합니다. 함수가 호출될 때마다 함수의 인수로 값이 전달되면서 복사하는 비용이 듭니다. 함수의 인수로 STL 컨테이너같은 객체 혹은 구조체 등을 넘길 때 이 복사 비용이 성능에 영향을 줄 수 있습니다. 다음 코드 예를 통해 값이 복사 형태로 동작하는 것을 확인해보세요.

※ call by value는 한글로 값에 의한 호출이라고 하기도 합니다.

 

#include <iostream>

using namespace std;

void modify(int value) {
  value = 10; // ② 새 공간의 value 변경
  cout << "주소 " << &value << endl; // 주소 : 0x7fff84f16e5c
  cout << "값 : " << value << endl; //. ③ 변경한 값 출력 / 값 : 10
  // ④ 함수가 종료되면 modify( ) 함수의 value는 메모리에서 사라짐
}

int main() {
  int value = 5;
  cout << "주소 : " << &value << endl; // 주소 : 0x7fff84f16e74
  cout << "값 : " << value << endl; // 값 : 5
  modify(value); // ① modify( ) 함수 호출
  cout << "값 : " << value << endl; // ⑤ main( ) 함수 value 값은 그대로 / 값 : 5

  return 0;
}

 

코드 예를 그림으로 나타내면 다음과 같습니다. ① modify( ) 함수가 호출되면 전혀 다른 공간에 value 변수가 생기고 인수로 전달한 값이 복사됩니다. ② 이후에 modify( ) 함수에서 ③ value의 값을 10으로 바꾸지만 ④ 그 값은 modify( ) 함수 안의 값이므로 main( ) 함수의 value 변수에는 영향을 미치지 않습니다. ⑤ 따라서 modify( ) 함수가 종료되어도 main( ) 함수의 value 값은 그대로 5입니다.

※ 원 번호 순서를 다음 페이지에 나오는 그림과 맞춰 읽어보세요.

 

 

하지만 실제 값이 바뀌어야 하는 경우도 있습니다. 예를 들어 ‘크기가 1,000만인 정수형 배열을 포함한 객체’처럼 규모가 큰 객체를 함수의 인수로 넘길 때는 굳이 객체 전체를 복사하지 않고 레퍼런스를 활용해서 넘기기도 합니다. 이를 call by reference 방식이라고 합니다. 레퍼런스는 &라는 문법을 사용합니다. 이를 활용하면 변수 자체를 복사하지 않고 참조자를 통해 변수에 접근하고 수정할 수 있습니다. 코드 예는 다음과 같습니다.

※ call by reference는 참조에 의한 호출이라고 하기도 합니다.

 

#include <iostream>

using namespace std;

void modify(int& value) {
  value = 10; // ② main( )의 value값 자체 변경
  cout << "주소 " << &value << endl; // 주소 : 0x7fff6272fc34
  cout << "값 : " << value << endl; // 값 : 10
}

int main() {
  int value = 5;
  cout << "주소 : " << &value << endl; // 주소 : 0x7fff6272fc34
  cout << "값 : " << value << endl; // 값 : 5
  modify(value); // ① modify( ) 함수 호출
  cout << "값 : " << value << endl; // ③ main( ) 함수 value 값 변경 / 값 : 10

  return 0;
}

 

그림으로 그리면 다음과 같습니다. 이전 방식과 다르게 실제 main( ) 함수의 값이 수정되었죠?

 

 

참조값 전달과 주소값 전달의 공통점과 차이점은?

앞에서 그림과 함께 설명한 내용은 복사값과 참조값을 전달하는 방식의 차이였습니다. 그런데 참조값(레퍼런스 사용)이 아니라 주소값을 전달(포인터 사용)하여 함수 호출 시 전달된 인수를 수정하는 방식도 있습니다. 이 책에서 주소값을 전달하는 방식을 다루지 않은 이유는 이런 공통점과 차이점이 있어서입니다.

  • 공통점 1 : 실 인수값을 변경할 수 있습니다.
  • 차이점 1 : 참조값을 전달하면 참조 변수와 참조 대상 변수의 주소값이 일치하므로 메모리의 값을 읽고 쓰기 위한 추가 문법이 필요 없습니다.
  • 차이점 2 : 주소값을 전달하면 주소값을 전달받은 변수의 주소와 실제 변수의 주소값이 다릅니다. 그래서 주소값을 받기 위한 포인터 변수를 사용해야 합니다. 즉 포인터 문법이 필요합니다.

결국 정리하자면 두 방식은 ‘실 인수값을 변경한다’라는 목적에서는 차이가 없으나 포인터 문법을 사용하냐 마냐에서 차이가 있습니다. 제가 참조값 전달로 설명한 이유는 포인터 문법을 사용하면 다음 2가지의 불편함이 생기기 때문입니다.

  • 불편함 1 : 포인터를 사용하면 의도하지 않은 예외가 발생할 수 있습니다. 예를 들어 잘못된 주소에 접근할 수도 있습니다.
  • 불편함 2 : 포인터 문법은 간접 참조를 하므로 주소를 얻을 때와 값을 얻을 때의 문법이 다릅니다. 따라서 상대적으로 포인터의 문법이 좀 더 복잡합니다.

이런 이유로 이 책에서는 참조값 전달로 내용을 설명했습니다.

 

auto문

STL은 어떤 타입이라도 사용할 수 있도록 잘 구현되어 있습니다. 하지만 타입이 복잡해지면 사용할 때 실수하기 쉽고 코드도 길어지므로 가독성이 떨어질 수 있습니다. 이때 auto 키워드를 사용하면 변수의 타입을 자동으로 추론하기 때문에 코드가 더 간결해지고 유지 관리하기 쉬워집니다.

 

#include <iostream>
#include <vector>
#include <map>
#include <string>

using namespace std;

int main() {
  auto num = 42; // int로 추론
  cout << num << endl; // 출력값 : 42

  auto pi = 3.14159; // double로 추론
  cout << pi << endl; // 출력값 : 3.14159

  auto greeting = string("Hello, world!"); // string으로 추론
  cout << greeting << endl; // 출력값 : Hello, world!

  return 0;
}

 

범위 기반 반복문

배열이나 컨테이너의 모든 원소를 순회할 때 사용합니다. 기본 반복문보다 구현이 쉽고 가독성이 좋습니다. 다음과 같은 형식으로 사용합니다.

 

for (타입 변수명 : 컨테이너) {
  // 코드
}

 

실제 코드 예를 볼까요. 만약 코드 예의 컨테이너 문법이 이해되지 않으면 다음 절에서 설명하는 컨테이너 문법을 먼저 공부하고 오는 걸 추천합니다.

 

#include <iostream>
#include <vector>
#include <map>
#include <set>

using namespace std;

int main() {
  // vector 예
  vector<int> vec = {1, 2, 3, 4, 5};
  for (int num : vec) {
    cout << num << " ";
  }
  cout << endl;
  // 출력값 : 1 2 3 4 5

  // map 예
  map<string, int> fruitMap = {{"apple", 1}, {"banana", 2}, {"cherry", 3}};
  for (const auto& pair : fruitMap) {
    cout << pair.first << "=" << pair.second << " ";
  }
  cout << endl;
  // 출력값 : apple = 1 banana = 2 cherry = 3

  // set 예
  set<string> fruitSet = {"apple", "banana", "cherry"};
  cout << "Set: ";
  for (const auto& fruit : fruitSet) {
    cout << fruit << " ";
  }
  cout << endl;
  // 출력값 : apple banana cherry

  return 0;
}

 

STL 컨테이너와 사용할 때는 값을 수정할 필요가 없으므로 auto 대신 상수 레퍼런스를 적용한 const auto&를 사용했습니다. 컨테이너를 반복문에서 사용하거나 함수의 인수로 넘길 때는 항상 복사하는 비용을 고려해야 합니다. 수정해야 할 때는 레퍼런스를, 수정하지 않아야 할 때는 상수 레퍼런스 적용을 고려해보기 바랍니다.

 

2.2 반복자

반복자iterator는 C++에서 컨테이너(벡터, 셋, 맵 등)의 종류와 관계없이 원소들을 순회하고 접근할 수 있게 해줍니다. 만약 반복자가 없다면 개발자는 각 컨테이너의 구현 방식을 명확히 알아야 하고 이에 따른 접근 코드를 구현해야 합니다. 하지만 반복자를 사용하면 이런 것에 구애받지 않고 일관된 방식으로 다양한 컨테이너를 다룰 수 있습니다. 모든 컨테이너에 같은 방식으로 원소를 순회하거나 접근할 수 있으므로 컨테이너가 바뀌더라도 반복자로 접근하는 코드는 수정할 필요가 없습니다. 즉 유지보수와 재사용성이 크게 향상됩니다. 예를 들어 벡터와 맵을 순회한다고 할 때 반복자를 사용하면 같은 코드로 두 자료구조를 순회할 수 있습니다. 여기서는 다양한 반복자 중 코딩 테스트에 꼭 필요한 순방향 반복자와 역방향 반복자, 이 둘을 알아보겠습니다.

※ 벡터의 내부 구조는 배열, 맵은 이진 탐색 트리로 구성되어 있습니다. 반복자가 없다면 각 구성에 맞는 코드를 작성해서 순회해야 할 겁니다.

 

순방향 반복자

순방향 반복자forward iterator는 컨테이너의 원소를 순차적으로 순회할 수 있게 해줍니다. 순방향 반복자는 begin( )과 end( )가 쌍으로 나오는 경우가 많습니다. begin( )은 컨테이너의 첫 원소 위치를 나타내고, end( )는 컨테이너의 마지막 원소 위치의 다음을 나타냅니다. 컨테이너를 순회하는 과정이 있는 STL은 다음과 같이 2가지 특징을 가집니다.

  1. 대부분 시작 위치와 끝 위치를 받고 이때 시작 위치는 begin( ), 끝 위치는 end( )로 넘기는 경우가 많습니다. 이는 begin( )부터 end( ) 바로 직전까지 순회하라는 의미입니다.
  2. 특정 원소를 탐색하거나 조건에 맞는 원소를 찾는 STL의 경우에는 해당 원소를 찾으면 위치를 반환하고, 그렇지 않으면 end( )를 반환합니다.

코드 예를 보겠습니다. 먼저 벡터에서 원소를 순회, 출력한 후 find( ) 메서드를 통해 특정 원소를 탐색하는 코드 예를 본 후, 이후에 맵을 통해 같은 동작을 하는 코드 예를 보겠습니다. 두 코드에서 반복자를 사용하는 부분이 동일한 것에 주목하세요. 다음은 벡터에서 순방향 반복자를 사용하는 코드 예입니다.

 

#include <algorithm> // find 함수를 위한 헤더
#include <iostream>
#include <vector>

using namespace std;

int main() {
  vector<int> vec = {10, 20, 30, 40, 50};

  // 순회하고 출력
  for (auto it = vec.begin(); it != vec.end(); ++it) {

    cout << *it << " ";
  }
  cout << endl;
  // 출력값 : 10 20 30 40 50

  // 탐색
  auto result = find(vec.begin(), vec.end(), 30);
  if (result != vec.end()) {
    cout << "Found: " << *result << endl;
  } else {
    cout << "Not found" << endl;
  }
  // 출력값 : 30
  return 0;
}

 

다음은 맵에서 순방향 반복자를 사용하는 코드 예입니다.

 

#include <iostream>
#include <map>

using namespace std;

int main() {
  map<string, int> myMap = {{"apple", 1}, {"banana", 2}, {"cherry", 3}};

  // 순회 및 출력
  for (auto it = myMap.begin(); it != myMap.end(); ++it) {
    cout << it->first << ": " << it->second << endl;
  }
  /*
    apple: 1
    banana: 2
    cherry: 3
  */

  // 원소 탐색
  auto result = myMap.find("banana");
  if (result != myMap.end()) {
    cout << "Found: " << result->first << " -> " << result->second << endl;
  } else {
    cout << "Not found" << endl;
  }
  /*
    Found: banana -> 2
  */

  return 0;
}

 

역방향 반복자

역방향 반복자는 순방향 반복자와 방향이 반대입니다. 컨테이너의 끝에서 시작으로 이동하고 기본적인 개념은 순방향 반복자와 같습니다. 순방향 반복자와 다른 점은 ++ 연산자를 쓸 때 순방향 반복자는 다음 원소로 위치가 바뀌는데, 역방향 반복자는 이전 원소로 위치가 바뀐다는 것입니다. 그리고 순방향 반복자가 begin( ), end( )를 사용했다면, 역방향 반복자는 rbegin( )과 rend( )를 사용합니다. rbegin( )은 맨 마지막 원소의 위치이고 rend( )는 맨 처음 원소의 바로 직전 위치입니다. 방향만 다르고 원리는 같으므로 앞 벡터 코드에서 반복자만 역방향 반복자로 바뀐 코드 예를 보겠습니다.

 

#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

int main() {
  vector<int> vec = {10, 20, 30, 40, 50};

  // 순회하고 출력
  for (auto it = vec.rbegin(); it != vec.rend(); ++it) {
    cout << *it << " ";
  }
  cout << endl;
  // 출력값 : 50 40 30 20 10

  // 탐색
  auto result = find(vec.rbegin(), vec.rend(), 30);
  if (result != vec.rend()) {
    cout << "Found: " << *result << endl;
  } else {
    cout << "Not found" << endl;
  }
  // 출력값 : 30

  return 0;
}

 


STL의 컨테이너와 STL의 알고리즘에 대한 자세한 설명은 아래 글을 참고해주세요.

저자 박경록

매일 퇴근과 점심 메뉴를 고민하는 9년차 시스템 S/W 개발자입니다. 수학, 알고리즘 같은 실생활과 가깝고도 먼 학문을 좋아하고, 명확하지만 개선 여지가 있는 문제들에 대해 논의하고 사고를 개선해 나가는 과정을 좋아합니다.

1 Comment

Leave a Reply

©2020 GoldenRabbit. All rights reserved.
상호명 : 골든래빗 주식회사
(04051) 서울특별시 마포구 양화로 186, 5층 512호, 514호 (동교동, LC타워)
TEL : 0505-398-0505 / FAX : 0505-537-0505
대표이사 : 최현우
사업자등록번호 : 475-87-01581
통신판매업신고 : 2023-서울마포-2391호
master@goldenrabbit.co.kr
개인정보처리방침
배송/반품/환불/교환 안내