STL 알고리즘
Coddy C++ 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 104개 중 73번째.
STL 알고리즘은 반복자(iterator)에 의해 정의된 범위에서 작동하는 템플릿 함수입니다. 이들은 <algorithm> 및 <numeric> 헤더에서 찾을 수 있으며, 호환되는 반복자를 제공하는 모든 컨테이너와 함께 작동합니다.
std::sort는 기본적으로 요소를 오름차순으로 정렬합니다:
#include <algorithm>
#include <vector>
std::vector<int> nums = {5, 2, 8, 1};
std::sort(nums.begin(), nums.end());
// nums: {1, 2, 5, 8}std::find는 값을 검색하고 첫 번째 일치 항목에 대한 반복자를 반환하며, 찾지 못한 경우 end()를 반환합니다:
auto it = std::find(nums.begin(), nums.end(), 5);
if (it != nums.end()) {
std::cout << "Found at index: " << (it - nums.begin());
}std::transform은 각 요소에 연산을 적용하고 그 결과를 대상 범위에 저장합니다:
std::vector<int> doubled(nums.size());
std::transform(nums.begin(), nums.end(), doubled.begin(),
[](int x) { return x * 2; });
// doubled: {2, 4, 10, 16}<numeric>의 std::accumulate는 모든 요소를 하나의 값으로 결합합니다:
#include <numeric>
int sum = std::accumulate(nums.begin(), nums.end(), 0);
// sum: 16 (1 + 2 + 5 + 8)이 알고리즘들은 컨테이너를 직접 받는 대신 반복자 범위를 받아들이므로, 동일한 코드로 부분 범위나 서로 다른 컨테이너 타입에서도 작동할 수 있을 만큼 유연합니다.
챌린지
쉬움STL 알고리즘을 사용하여 일련의 숫자들을 처리하는 점수 분석기를 만들어 보겠습니다. sort, find, transform, 그리고 accumulate가 어떻게 함께 작동하여 데이터를 분석하는지 보여주는 유틸리티 함수들을 작성하게 됩니다.
코드는 다음 두 개의 파일로 구성합니다:
ScoreAnalyzer.h: 정수 벡터를 처리하기 위해 STL 알고리즘을 사용하는 유틸리티 함수들을 정의합니다.std::vector<int>&를 매개변수로 받아std::sort를 사용하여 오름차순으로 정렬하는sortScores함수를 만드세요.const std::vector<int>&와int대상 값을 매개변수로 받는findScore함수를 만드세요.std::find를 사용하여 대상 값을 검색합니다. 찾은 경우 인덱스(시작 지점으로부터의 거리)를 반환하고, 찾지 못한 경우-1을 반환하세요.const std::vector<int>&와int보너스 금액을 매개변수로 받는applyBonus함수를 만드세요.std::transform을 사용하여 각 점수에 보너스가 더해진 새로운 벡터를 생성하고 반환하세요.const std::vector<int>&를 매개변수로 받아 평균을double로 반환하는calculateAverage함수를 만드세요.std::accumulate를 사용하여 합계를 계산한 다음, 크기로 나누세요.const std::vector<int>&를 매개변수로 받아 모든 요소를 공백으로 구분하여 출력하고 그 뒤에 줄바꿈을 출력하는printVector함수를 만드세요.main.cpp: 여섯 개의 입력값(각각 별도의 줄에 입력됨)을 읽습니다:- 첫 번째 점수 (정수)
- 두 번째 점수 (정수)
- 세 번째 점수 (정수)
- 네 번째 점수 (정수)
- 검색할 점수 (정수)
- 적용할 보너스 금액 (정수)
네 개의 점수로 벡터를 생성하고 알고리즘을 시연하세요:
Original:뒤에 벡터 내용을 출력합니다.- 점수를 정렬하고
Sorted:뒤에 정렬된 벡터를 출력합니다. - 정렬된 벡터에서 대상 점수를 검색합니다. 찾은 경우
Found <value> at index <index>를 출력합니다. 찾지 못한 경우<value> not found를 출력합니다. - 정렬된 점수에 보너스를 적용하고
With bonus:뒤에 새 벡터를 출력합니다. - 원래의 정렬된 점수(보너스 적용 전)의 평균을 계산하여 소수점 첫째 자리까지
Average: <value>형식으로 출력합니다.
예를 들어, 입력값이 75, 90, 60, 85, 85, 5인 경우:
Original: 75 90 60 85
Sorted: 60 75 85 90
Found 85 at index 2
With bonus: 65 80 90 95
Average: 77.5입력값이 100, 80, 95, 70, 50, 10인 경우:
Original: 100 80 95 70
Sorted: 70 80 95 100
50 not found
With bonus: 80 90 105 110
Average: 86.2sort, find, transform을 위해 <algorithm>을, accumulate를 위해 <numeric>을 포함하는 것을 잊지 마세요. 평균 형식을 맞추기 위해 <iomanip>의 std::fixed와 std::setprecision(1)을 사용하세요.
치트 시트
STL 알고리즘은 반복자(iterator)로 정의된 범위에서 작동하는 <algorithm> 및 <numeric>의 템플릿 함수입니다.
std::sort는 요소를 오름차순으로 정렬합니다:
#include <algorithm>
#include <vector>
std::vector<int> nums = {5, 2, 8, 1};
std::sort(nums.begin(), nums.end());
// nums: {1, 2, 5, 8}std::find는 값을 검색하고 첫 번째 일치 항목에 대한 반복자를 반환하거나, 찾지 못한 경우 end()를 반환합니다:
auto it = std::find(nums.begin(), nums.end(), 5);
if (it != nums.end()) {
std::cout << "Found at index: " << (it - nums.begin());
}std::transform은 각 요소에 연산을 적용하고 그 결과를 대상 범위에 저장합니다:
std::vector<int> doubled(nums.size());
std::transform(nums.begin(), nums.end(), doubled.begin(),
[](int x) { return x * 2; });
// doubled: {2, 4, 10, 16}<numeric>의 std::accumulate는 모든 요소를 하나의 값으로 결합합니다:
#include <numeric>
int sum = std::accumulate(nums.begin(), nums.end(), 0);
// sum: 16 (1 + 2 + 5 + 8)이러한 알고리즘은 반복자 범위와 함께 작동하므로 부분 범위나 다양한 컨테이너 유형에 유연하게 대응할 수 있습니다.
직접 해보기
#include <iostream>
#include <vector>
#include <iomanip>
#include "ScoreAnalyzer.h"
using namespace std;
int main() {
// 6개의 입력값 읽기
int score1, score2, score3, score4;
int searchTarget, bonusAmount;
cin >> score1;
cin >> score2;
cin >> score3;
cin >> score4;
cin >> searchTarget;
cin >> bonusAmount;
// TODO: 4개의 점수를 포함하는 vector 생성
// TODO: "Original:"을 출력한 뒤 vector의 내용을 출력
// TODO: 점수들을 정렬하고 "Sorted:"를 출력한 뒤 정렬된 vector를 출력
// TODO: 정렬된 vector에서 searchTarget 점수를 검색
// 찾은 경우, "Found <value> at index <index>"를 출력
// 찾지 못한 경우, "<value> not found"를 출력
// TODO: 정렬된 점수들에 보너스를 적용하고 "With bonus:"를 출력한 뒤 새로운 vector를 출력
// TODO: 정렬된 점수들의 평균(보너스 적용 전)을 계산하고 출력
// 서식 지정을 위해 fixed와 setprecision(1)을 사용
// "Average: <value>" 형식으로 출력
return 0;
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.