예시코드)
https://github.com/GbLeem/CPP_Study/tree/main/NoCode
53.cpp ~ 61.cpp
#include<iostream>
#include<vector>
int main()
{
std::vector<int>nums{ 0,1,2,3,4 };
std::cout << nums.size() << std::endl; //5
nums.emplace_back(5); //맨 뒤에 숫자 삽입
nums.pop_back(); //맨 뒤에것 삭제
//ranged for 방식으로 iterate
for (const int& num : nums)
{
std::cout << num << std::endl; //0 1 2 3 4
}
}
#include<iostream>
#include<vector>
class Cat
{
public:
explicit Cat(int age)
:mAge{age}
{}
void speak() const
{
std::cout << "Cat " << mAge << std::endl;
}
private:
int mAge;
};
int main()
{
std::vector<Cat>catVec;
catVec.emplace_back(Cat{ 1 });
catVec.emplace_back(Cat{ 2 });
catVec.emplace_back(Cat{ 3 });
catVec.emplace_back(Cat{ 4 });
for (const auto& cats : catVec)
{
cats.speak();
}
}
#include<iostream>
#include<vector>
int main()
{
std::vector<int>nums(10000, 1); //1을 10000개 넣음
nums.emplace_back(2); //O(1)
nums.pop_back(); //O(1)
nums.emplace(nums.begin(), 3); //O(n)
nums.erase(nums.begin()); //O(n)
return 0;
}
emplace_back() 최적화 사용하기
cats.emplace_back(Cat{ "kitty",2 });
처럼 사용하면 temp 객체가 생성되고 move operation이 한 번 작동한다. (필요없는 move operation)
-> 아래 그림 참고
cats.emplace_back("kitty",2);
를 사용할 경우 temp 객체가 생성되지 않고 바로 삽입한다.
-> emplace_back()은 object의 refenece를 반환한다.(C++17)
Cat& cat= cats.emplace_back("kitty", 2);
#include<iostream>
#include<string>
#include<vector>
class Cat
{
public:
explicit Cat(std::string name, int age)
:mName{ name }
, mAge{ age }
{}
void speak() const
{
std::cout << "Cat " << mName << mAge << std::endl;
}
private:
std::string mName;
int mAge;
};
int main()
{
std::vector<Cat>cats;
cats.emplace_back(Cat{ "cat0",0 });
cats.emplace_back(Cat{ "cat1",1 });
//cats.emplace_back(Cat{ "kitty",2 }); bad
cats.emplace_back("kitty", 2); //better
//참고
Cat nabi{"nabi", 3};
cats.emplace_back(nabi);// copy
cats.emplace_back(std::move(nabi));// move
return 0;
}
reserve()
함수로 공간을 확보해두면 문제가 발생하지 않는다.std::cout << nums.size() << std::endl; //0
nums.reserve(10000);
std::cout << nums.capacity() << std::endl; //10000
#include<iostream>
#include<vector>
#include<string>
class Cat
{
public:
explicit Cat(std::string name)
:mName{ std::move(name) }
{
std::cout << mName << " cat constructor" << std::endl;
}
~Cat()
{
std::cout << "cat destructor" << std::endl;
}
Cat(const Cat& other)
:mName(other.mName)
{
std::cout << mName << " copy constructor" << std::endl;
}
Cat(Cat&& other)
:mName(other.mName)
{
std::cout << mName << " move constructor" << std::endl;
}
private:
std::string mName;
};
int main()
{
std::vector<Cat>cats;
cats.emplace_back("kitty");
cats.emplace_back("nabi");
return 0;
//<출력>
//kitty cat constructor
//nabi cat constructor
//kitty copy constructor
//cat destructor
//cat destructor
//cat destructor
}
cats.reserve(2);
//index base
for (int i = 0; i < 1000; ++i)
{
for (std::size_t idx = 0; idx < numsA.size(); ++idx)
{
numsA[idx] *= 2;
}
}
//iterator base
for (auto iter = numsB.begin(); iter != numsB.end(); ++iter)
{
(*iter) *= 2;
}
//ranged for loop
for (auto& num : numsC)
{
num *= 2;
}
remove()
는 iterator를 반환한다.auto iter = std::remove(nums.begin(), nums.end(), 0);
#include<iostream>
#include<vector>
#include<string>
int main()
{
std::vector<int>nums{ 0,1,0,1,0,1,0 };
for (int num : nums)
{
std::cout << num << " "; //0 1 0 1 0 1 0
}
std::cout << std::endl;
nums.erase(std::remove(nums.begin(), nums.end(), 0), nums.end());
for (int num : nums)
{
std::cout << num << " "; //1 1 1
}
std::cout << std::endl;
//람다 expression으로 짝수 삭제
std::vector<int>nums2{ 0,1,2,3,4,5,6 };
nums2.erase(std::remove_if(nums2.begin(), nums2.end(), [](int n)
{
if (n % 2 == 0)
return true;
return false;
}), nums2.end());
for (int num2 : nums2)
{
std::cout << num2 << " "; //1 3 5
}
std::cout << std::endl;
reserve()
로 공간을 미리 확보하면 속도 보완 가능)#include<array>
필요std::array<int, 100> nums;
std::sort(시작, 끝, callable object);
#include<iostream>
#include<algorithm>
#include<vector>
int main()
{
std::vector<int>nums{ 1,3,4,5,100,2,66 };
std::sort(nums.begin(), nums.end());
for (auto num : nums)
{
std::cout << num << " "; //1 2 3 4 5 66 100
}
std::cout << std::endl;
return 0;
}
#include<functional>
#include<vector>
#include<algorithm>
#include<iostream>
int main()
{
const std::vector<int>nums{ 0,1,2,3,4 };
const auto resultIter = std::find(nums.begin(), nums.end(), 2); //2를 찾음
if (resultIter != nums.end())
{
std::cout << "idx: " << std::distance(nums.begin(), resultIter) << std::endl; //idx : 2
}
else
{
std::cout << "no elem found" << std::endl;
}
}
#include <iostream>
#include <vector>
#include <numeric>
#include <string>
#include <functional>
int main()
{
std::vector<int> v{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int sum = std::accumulate(v.begin(), v.end(), 0);
int product = std::accumulate(v.begin(), v.end(), 1, std::multiplies<int>());
std::cout << "sum: " << sum << '\n'<< "product: " << product << '\n';
// sum: 55 product: 3628800
}
std::array < std::array<int, 3>, 3> fixedMatrix;
std::vector<std::vector<int>> dynamicMatrix(3, std::vector <int>(3));
#include<array>
#include<vector>
#include<iostream>
template<typename T, int ROW, int COL>
class Matrix
{
public:
Matrix(int ROW, int COL)
:mMatrix(ROW* COL, 0)
{
}
T& operator()(int rowIdx, int colIdx)
{
const int idx = rowIdx * COL + colIdx;
return mMatrix[idx];
}
private:
std::vector<T>mMatrix;
};
int main()
{
Matrix<int,10,10> mat(10, 10);
mat(3, 3) = 3;
mat(4, 3) = mat(3, 3) * 10;
std::cout << mat(4, 3) << std::endl;
return 0;
}
#include <iostream>
#include <deque>
int main()
{
std::deque<int> d = { 7, 5, 16, 8 };
d.emplace_front(13);
d.emplace_back(25);
for (int n : d)
{
std::cout << n << ' '; //13 7 5 16 8 25
}
}