C++ 벡터: for 루프에서 std::transform으로 변환
예제:
#include <vector>
#include <algorithm>
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
// for 루프를 사용하여 벡터 값 제곱
for (int i = 0; i < vec.size(); ++i) {
vec[i] *= vec[i];
}
// std::transform을 사용하여 벡터 값 제곱
std::transform(vec.begin(), vec.end(), vec.begin(),
[](int x) { return x * x; });
// 결과 출력
for (int i : vec) {
std::cout << i << " ";
}
return 0;
}
설명:
for 루프:
vec.size()
만큼 반복하며 각 요소에 접근합니다.- 현재 요소를 자기 자신과 곱하여 제곱 값으로 변경합니다.
std::transform:
vec.begin()
부터vec.end()
까지 반복하며 각 요소에 람다 함수를 적용합니다.- 람다 함수는 입력값
x
를 받아 제곱 값x * x
를 반환합니다. - 반환된 값은 원본 벡터에 동일한 위치에 저장됩니다.
std::transform 사용의 장점:
- 코드가 더욱 간결하고 명확합니다.
- for 루프의 반복 조건 및 인덱스 관리를 따로 처리할 필요가 없어 코드가 더욱 읽기 쉽습니다.
- 람다 함수를 사용하여 다양한 변환 작업을 간편하게 수행할 수 있습니다.
- 알고리즘으로 구현되어 있어 병렬 처리가 가능합니다 (컴파일러와 하드웨어가 지원하는 경우).
주의:
std::transform
은 원본 범위와 결과 범위가 동일해야 합니다.- 람다 함수는 입력값을 변경하지 않고 새로운 값을 반환해야 합니다.
결론
예제 코드: 벡터 요소 제곱 및 문자열 대문자 변환
#include <vector>
#include <algorithm>
int main() {
std::vector<int> numbers = {1, 2, 3, 4, 5};
// for 루프 사용
for (int i = 0; i < numbers.size(); ++i) {
numbers[i] *= numbers[i];
}
// std::transform 사용
std::transform(numbers.begin(), numbers.end(), numbers.begin(),
[](int x) { return x * x; });
// 결과 출력
for (int n : numbers) {
std::cout << n << " ";
}
return 0;
}
numbers
벡터를 선언하고 초기화합니다.for
루프와std::transform
을 사용하여 벡터 요소를 제곱합니다.- 결과를 출력합니다.
문자열 대문자 변환:
#include <vector>
#include <algorithm>
#include <string>
int main() {
std::vector<std::string> words = {"hello", "world", "cplusplus"};
// for 루프 사용
for (std::string& word : words) {
std::transform(word.begin(), word.end(), word.begin(),
[](char c) { return std::toupper(c); });
}
// 결과 출력
for (const std::string& word : words) {
std::cout << word << " ";
}
return 0;
}
for
루프와std::transform
을 사용하여 벡터에 저장된 각 문자열을 대문자로 변환합니다.
추가 예제
다음은 std::transform을 사용하여 수행할 수 있는 몇 가지 다른 작업의 예입니다.
- 두 벡터의 요소를 더하거나 빼기
- 벡터 요소를 특정 값으로 나누기
- 벡터 요소에 조건에 따라 새로운 값 할당
- 두 범위의 요소를 쌍으로 묶어 새로운 컨테이너 만들기
결론
C++ 벡터 for 루프 대신 std::transform 사용: 대체 방법
for 루프와 직접적인 함수 호출:
#include <vector>
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
// for 루프와 직접적인 함수 호출
for (int i = 0; i < vec.size(); ++i) {
vec[i] = square(vec[i]); // square() 함수를 직접 호출
}
// 결과 출력
for (int i : vec) {
std::cout << i << " ";
}
return 0;
}
int square(int x) {
return x * x;
}
- 벡터 요소를 순회하며
square()
함수를 직접 호출하여 제곱 값을 구합니다. square()
함수는 별도로 작성하여 벡터 요소를 제곱하는 작업을 담당합니다.
장점:
- 간단하고 직관적인 코드입니다.
- for 루프와 함수 호출을 명확하게 구분할 수 있습니다.
단점:
std::transform
에 비해 코드가 다소 길어질 수 있습니다.- 람다 함수를 사용할 수 없어 함수를 별도로 작성해야 합니다.
- 병렬 처리가 어려울 수 있습니다.
std::for_each:
#include <vector>
#include <algorithm>
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
// std::for_each 사용
std::for_each(vec.begin(), vec.end(), [](int& x) { x *= x; });
// 결과 출력
for (int i : vec) {
std::cout << i << " ";
}
return 0;
}
std::for_each
알고리즘을 사용하여 벡터 요소마다 람다 함수를 적용합니다.- 람다 함수는 입력값
x
를 참조로 받아 제곱 값으로 변경합니다.
std::transform
과 비슷하게 간결하고 명확한 코드입니다.- for 루프 구조를 사용하지 않아 코드가 더욱 읽기 쉽습니다.
std::transform
과 달리 결과 범위를 따로 지정할 수 없습니다.- 람다 함수가 입력값을 변경해야 하는 경우 사용하기 어려울 수 있습니다.
커스텀 알고리즘:
#include <vector>
#include <algorithm>
template <typename T>
void square_inplace(std::vector<T>& vec) {
for (T& x : vec) {
x *= x;
}
}
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
// 커스텀 알고리즘 사용
square_inplace(vec);
// 결과 출력
for (int i : vec) {
std::cout << i << " ";
}
return 0;
}
square_inplace
라는 이름의 템플릿 함수를 정의합니다.- 이 함수는 벡터를 입력값으로 받아 벡터 요소를 제곱합니다.
main
함수에서square_inplace
함수를 벡터에 호출하여 값을 변환합니다.
- 코드 재사용성을 높일 수 있습니다.
- 여러 벡터에 동일한 변환 작업을 적용해야 하는 경우 유용합니다.
- 알고리즘의 동작을 명확하게 제어할 수 있습니다.
std::transform
이나std::for_each
보다 코드 작성량이 늘어날 수 있습니다.- 함수 템플릿을 사용하여 일반화해야 하기 때문에 복잡도가 높아질 수 있습니다.
결론
c++ std