C++ Sample

mohadang·2023년 1월 2일
0

C++ Sample

목록 보기
1/1
post-thumbnail

코딩 테스트시 자주 보는 코드


//C 표준 stream과 C++ 표준 stream의 동기화를 끊는다.
//기본값 true 이면 입출력이 순서대로 동기적으로 출력
ios::sync_with_stdio(0);

//cin을 cout으로부터 untie 한다. stream을 tie하면 다른 stream에서 입출력요청이 오기전에 stream을 flush시킨다.
cin.tie(0);
cout.tie(0);

//cin, cout이 scanf, printf에 비해서 속도가 많이 느리다.
//따라서 속도를 보다 가속시키기 위해 사용한다.

권장 사용 방법

해당 방법을 사용하여 C++ 입출력 객채를 가속시켜서 사용할 목적이라면 다음의 세 가지 방법을 권장한다.
1. scanf와 printf와 섞어서 사용하지 않기
2. 싱글 쓰레드 환경에서만 사용하기
3. 그럼에도 시간초과가 발생하면 C 표준입출력 함수들을 사용하기

substr

#include <iostream>

int main(void) {
  const std::string str = "0123456789";
  {
    std::string sub = str.substr(5);//index
    std::cout << sub << std::endl;//56789
  }
  {
    std::string sub = str.substr(5, 3);//index, len
    std::cout << sub << std::endl;//567
  }
  {
    std::string sub = str.substr(5, 50);
    std::cout << sub << std::endl;//56789
  }
  
  try {
    // pos 가 문자열 범위 밖이므로 예외를 발생시킴.
    std::string sub = str.substr(
      str.size() + 3, //out of index
      50);
    std::cout << sub << std::endl;//pos exceeds string size
  } catch (const std::out_of_range& e) {
    std::cout << "pos exceeds string size" << std::endl;;
  }
  return 0;
}

stoi

#include <iostream>

int main(void) {
  //C++ cout
  std::cout << "stoi : " << std::stoi("22") << std::endl;
  std::cout << "stol : " << std::stol("2144967290") << std::endl;
  std::cout << "stof : " << std::stof("3.4") << std::endl;
  std::cout << "stod : " << std::stod("2.11") << std::endl;
  return 0;
}

min/max

#include <iostream>

int main(void) {
  std::cout << std::min(1, 2) << std::endl;//1
  std::cout << std::min(1, 2) << std::endl;//1
  std::cout << std::min('a', 'c') << std::endl;//a
  std::cout << std::min(34.5, 12.3) << std::endl;//12.3

  std::cout << std::max(1, 2) << std::endl;//2
  std::cout << std::max(1, 2) << std::endl;//2
  std::cout << std::max('a', 'c') << std::endl;//c
  std::cout << std::max(34.5, 12.3) << std::endl;//34.5
  return 0;
}

~MIN/~MAX

#include <iostream>
#include <limits.h>

int main(void) {
  std::cout << INT_MAX << std::endl;
  std::cout << INT_MIN << std::endl;
  std::cout << UINT_MAX << std::endl;
  std::cout << LLONG_MAX << std::endl;
  std::cout << LLONG_MIN << std::endl;
  return 0;
}

front/back

#include <iostream>
#include <vector>

int main() {
  {
    std::string str = "test string";
    str.front() = 'T';
    std::cout << str << std::endl;//Test string
  }

  {
    std::string str("hello world.");
    str.back() = '!';
    std::cout << str << std::endl;//hello world!
  }

  std::vector<int> vec{ 1,2,3 };
  vec.front() = 5;
  std::cout << vec[0] << vec[1] << vec[2] << std::endl;//523

  return 0;
}

vector 초기화 : 길이 5, 값 1

#include <iostream>
#include <vector>

int main() {
  std::vector<int> nums(5, 1);
  for (int num : nums) {
    std::cout << num;
  }
  //11111
  return 0;
}

vector 초기화 : 함수에 바로 전달

#include <iostream>

class Test {
  int data_;
public:
  Test(int data) : data_(data) {
  }
  Test(const Test& t) {
    std::cout << "copy" << std::endl;
  }
  void Print() {std::cout << data_ << std::endl;}
};
void func1(std::vector<int> vec) {
  for(const auto& item : vec) {
    std::cout << item;
  }
  std::cout << std::endl;
}
void func2(Test t) {
  t.Print();
}
int main() {
  func1(std::vector<int>{1,2,3,4});
  func2(Test(3));//dose not call copy
}

구조체 초기화

struct Employee {
  int age;
  std::string name;
};

int main() {

  Employee e{109, "Zed"};

  // stack, queue는 안됨
  // std::stack<Employee> con =  X
  // std::queue<Employee> con =  X

  // std::list<Employee> con =
  std::vector<Employee> con =
  {
    {108, "Zaphord"},
    {32, "Arthur"},
    {108, "Ford"},
  };
  con.emplace_back(e);

  for (const auto& item : con) {
    std::cout << item.age << ", " << item.name << std::endl;
  }
}

vector remove, O(n)

#include <iostream>
#include <algorithm>

int main() {
  std::vector<int> nums{0,0,0,0,0,0,1,1,1,0,0,0};
  auto it = std::remove(nums.begin(), nums.end(), 0);
  // auto it = std::remove_if(nums.begin(), nums.end(), [](int n) {
  //   return n == 0;
  // });

  for (int num : nums) {
    std::cout << num << " ";
  }
  std::cout << std::endl;
  //1 1 1 0 0 0 1 1 1 0 0 0
  //0이 아닌 값들을 앞으로 땡김
  //it 는 제거할 위치의 iterator 가리킴  

  nums.erase(it, nums.end());
  for (int num : nums) {
    std::cout << num << " ";
  }
  //1 1 1
  //it 부터 end까지의 메모리를 해제

  return 0;
}

iterator

#include <iostream>
#include <vector>

int main() {
  std::vector<int> vec{ 1, 3, 4, 5, 9 };
  
  std::vector<int>::iterator it = vec.begin();
  for (;it != vec.end(); ++it) {
    std::cout << *it;
  }
  std::cout << std::endl;
  
  std::vector<int>::reverse_iterator r_it = vec.rbegin();
  for (;r_it != vec.rend(); ++r_it) {
    std::cout << *r_it;
  }
  std::cout << std::endl;
  
  std::vector<int>::const_iterator c_it = vec.begin();
  for (;c_it != vec.end(); ++c_it) {
    std::cout << *c_it;
    // *c_it = 10;//error
  }
  std::cout << std::endl;

  std::vector<int>::const_reverse_iterator cr_it = vec.rbegin();
  for (;cr_it != vec.rend(); ++cr_it) {
    std::cout << *cr_it;
    // *cr_it = 10;//error
  }
  std::cout << std::endl;

  return 0;
}

iterator 초기화(begin(), end())

#include <iostream>
#include <queue>

int main() {
  std::vector<int> nums{'a', 'c', 'f', 'd', 'b'};

  std::priority_queue<int> pq(nums.begin(), nums.end());
  while (pq.empty() == false) {
    std::cout << (char)pq.top() << std::endl;
    pq.pop();
  }

  std::string str(nums.begin(), nums.end());
  std::cout << str << std::endl;

  return 0;
}

vector 에서 문자열로 변경

#include <iostream>
#include <vector>

int main() {
  std::vector<char> vec{ 'A', 'B', 'C' };
  std::string str(vec.begin(), vec.end());
  std::cout << str << std::endl;// ABC

  //주의 !! : 유효한 아스키 코드값이 아니면 제대로 출력 안됨
  std::vector<int> nums{4, 65/*A*/, 7, 3, 8, 5, 2, 6};
  std::string not_str(nums.begin(), nums.end());
  std::cout << not_str << std::endl;//A만 보이고 나머지 문자는 제대로 출력 안됨

  return 0;
}

algorithm sort

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

int main() {
  std::vector<std::vector<int>> intervals;
  intervals.emplace_back(std::vector<int>{1, 3, 2});
  intervals.emplace_back(std::vector<int>{3, 1, 2});
  intervals.emplace_back(std::vector<int>{2, 3, 1});
  intervals.emplace_back(std::vector<int>{3, 2, 1});
  intervals.emplace_back(std::vector<int>{1, 2, 3});
  intervals.emplace_back(std::vector<int>{2, 1, 3});

  std::sort(intervals.begin(), intervals.end(),
    [](const std::vector<int>& it1, const std::vector<int>& it2) {
      for (int i = 0; i < it1.size(); ++i) {
        if (it1[i] == it2[i]) {
          continue;
        }
        return it1[i] < it2[i];
      }
      return true;
    });


  for (std::vector<int>& item : intervals) {
    std::cout << item[0] << item[1] << item[2] << std::endl;
  }
  //123
  //132
  //213
  //231
  //312
  //321
  return 0;
}

stable_sort

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

struct Employee {
  int age;
  std::string name;
};
bool operator<(const Employee& left, const Employee& right) {
  return left.age < right.age;
}

int main() {

  std::vector<Employee> v =
  {
    {108, "Zaphord"},
    {32, "Arthur"},
    {108, "Ford"},
  };

  std::stable_sort(v.begin(), v.end());
  for (const auto& item : v) {
    std::cout << item.age << ", " << item.name << std::endl;
  }

	// 32, Arthur
  // 108, Zaphord
  // 108, Ford  
  // Zaphord, Ford 사이의 순서는 유지한 상태에서 정렬한다.

  return 0;
}

partial_sort

/*
일부만 정렬

ex) 가장 작은 값 3개를 뽑고 싶다
  - Top3, Top5 를 뽑을때.

- 왜 굳이 partial_sort 사용?? 그냥 sort 안됨
  - 성능, 그냥 sort보다 시간 복잡도 작음
  - N log(middle-first)
*/



#include <algorithm>
#include <array>
#include <iostream>

int main() {
  //get Top 3  
  std::array<int, 10> s{ 5, 7, 4, 2, 8, 6, 1, 9, 0, 3 };

  std::partial_sort(s.begin(), s.begin() + 3, s.end());
  //0 1 2 7 8 6 5 9 4 3 
  
  std::partial_sort(s.begin(), s.begin() + 3, s.end(), std::greater<int>());
  //9 8 7 0 1 2 5 6 4 3 
  
  std::partial_sort(s.begin(), s.begin() + 3, s.end(), [](const auto& a, const auto &b ){
      return a < b;
  });
  //0 1 2 9 8 7 5 6 4 3    
    
  for (int a : s) {
    std::cout << a << " ";
  }
}

stringstream

#include <iostream>
#include <sstream>

int main() {
  std::stringstream stm;
  stm << "Hello my age is " << 18 << '!';
  std::cout << stm.str() << std::endl;//Hello my age is 18!
  return 0;
}

stack

#include <iostream>
#include <stack>

int main() {
  std::stack<int> s;
  //push
  s.push(3);
  s.push(2);
  s.emplace(1);

  //top
  std::cout << s.top() << std::endl;//1

  // pop
  s.pop();//del 1
  s.pop();//del 2

  //size
  std::cout << s.size() << std::endl;//1

  //empty
  std::cout << (s.empty() ? "Yes" : "No") << std::endl;//No

  return 0;
}

queue

#include <iostream>
#include <queue>

int main() {
  std::queue<int> q;

  // push
  q.push(1);
  q.push(2);
  q.push(3);
  q.push(4);
  q.emplace(5);

  // pop
  q.pop();

  std::cout << q.front()<< std::endl;//2
  std::cout << q.back() << std::endl;//5
  std::cout << q.size() << std::endl;//4
  std::cout << (q.empty() ? "Yes" : "No") << std::endl;//No

  return 0;
}

priority_queue

#include <iostream>
#include <queue>

int main() {

  std::priority_queue<int> p_qu_l;
  p_qu_l.push(1);
  p_qu_l.push(9);
  p_qu_l.emplace(5);
  while (p_qu_l.empty() == false) {
    std::cout << p_qu_l.top();
    p_qu_l.pop();
  }
  std::cout << std::endl;
  //951

  //1: element type for priority_queue
  //2: container type for priority_queue
  //3: Compare for priority_queue
  std::priority_queue<int, std::vector<int>, std::greater<int>> p_qu_g;//std::less<int>
  
  p_qu_g.push(1);
  p_qu_g.push(9);
  p_qu_g.emplace(5);
  while (p_qu_g.empty() == false) {
    std::cout << p_qu_g.top();
    p_qu_g.pop();
  }
  std::cout << std::endl;
  //159

  return 0;
}

k th min value

#include <iostream>
#include <queue>

int main() {
  
  std::vector<int> nums{4, 1, 7, 3, 8, 5, 2, 6};
  int k = 3;

  std::priority_queue<int, std::vector<int>, std::greater<int>> p_q(nums.begin(), nums.end());
  
  int kth_smallest_num = p_q.top();
  for (int i = 0; i < k; ++i) {
    kth_smallest_num = p_q.top();
    p_q.pop();
  }
  std::cout << kth_smallest_num << std::endl;

  return 0;
}

pair

#include <iostream>
#include <stack>

int main() {
  std::stack<std::pair<int, int>> s;
  //push
  s.push(std::make_pair<int, int>(1, 2));
  //s.push(std::make_pair(1, 2));
  s.emplace(2, 3);
  s.emplace(4, 5);

  //top
  std::pair<int, int> top_item = s.top();
  std::cout << top_item.first << top_item.second << std::endl;

  return 0;
}

tuple

#include <iostream>
#include <stack>
#include <tuple>

int main() {
  std::stack<std::tuple<int, int, std::string>> s;
  //push
  s.push(std::make_tuple<int, int, std::string>(1, 2, "apple"));
  //s.push(std::make_tuple(1, 2, "apple"));
  s.emplace(2, 3, "base");
  s.emplace(4, 5, "car");

  //top
  std::tuple<int, int, std::string> top_item = s.top();
  std::cout 
    << std::get<0>(top_item) 
    << std::get<1>(top_item) 
    << std::get<2>(top_item) << std::endl;//45car

  return 0;
}

nth_element


/*
nth_element 는 first 부터 last 전 까지의 원소들을 부분적으로 정렬합니다. 이 때, 정렬하는 방식은 다음과 같습니다.

nth 가 가리키고 있는 원소는 first 부터 last 전 까지의 모든 원소들을 정렬하였을 때 자리할 원소로 바뀝니다.

새로운 nth 가 가리키고 있는 원소 앞에 오는 원소들은 nth 가 가리키는 원소 뒤에 오는 원소들보다 작거나 같습니다.

* quick sort에서 pivot을 두고 각각 정렬 하는 동작이다.

*/

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

void nth_elem(int idx) {
  std::vector<int> v{ 8, 0, 4, 3, 2, 6, 5, 7, 9, 1 };
  auto m = v.begin() + idx;
  std::nth_element(v.begin(), m, v.end());
  std::cout << "nth is " << v[idx] << std::endl;
  for (int n : v) {
    std::cout << n << " ";
  }
  std::cout << std::endl;
}

int main() {
  nth_elem(0);
  // nth is 0
  // 0 1 4 3 2 6 5 7 9 8
  // index 0에 정렬된 원소가 있다 
  
  nth_elem(1);
  // nth is 1
  // 0 1 4 3 2 6 5 7 9 8 
  // index 1 에 정렬된 원소가 있다 
  // index 1 앞에는 index 1의 원소보다 작은값, 뒤에는 큰값


  nth_elem(5);
  // nth is 5
  // 1 0 3 2 4 5 6 7 9 8   
  // index 5 에 정렬된 원소가 있다 
  // index 5 앞에는 index 5의 원소보다 작은값, 뒤에는 큰값

  std::vector<int> v{5, 6, 4, 3, 2, 6, 7, 9, 3};
  std::nth_element(v.begin(), v.begin() + v.size() / 2, v.end());
  std::cout << "중간값은 " << v[v.size() / 2] << '\n';

  std::nth_element(v.begin(), v.begin() + 1, v.end(), std::greater<int>());
  std::cout << "두 번째로 큰 원소는 " << v[1] << '\n';
}

accumulate

#include <iostream>
#include <vector>
#include <numeric>

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);
  std::cout << sum << std::endl;
  int product = std::accumulate(v.begin(), v.end(), 1, std::multiplies<int>());
  std::cout << product << std::endl;
}
// 55
// 3628800

find_end

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

int main() {
  std::vector<int> v{ 1, 2, 3, 4 };
  int n1 = 3;
  int n2 = 5;

  auto result1 = std::find(begin(v), end(v), n1);
  auto result2 = std::find(begin(v), end(v), n2);
  auto result3 = std::find_if(begin(v), end(v), [](int i) { return i % 2 == 0; });

  (result1 != std::end(v)) ? 
    std::cout << "contains" << std::endl : 
    std::cout << "not contain" << std::endl;

  (result2 != std::end(v)) ? 
    std::cout << "contains" << std::endl: 
    std::cout << "not contain" << std::endl;

  (result3 != std::end(v)) ? 
    std::cout << "contains" << std::endl: 
    std::cout << "not contain" << std::endl;

	// contains
  // not contain
  // contains
}

min/max element

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

int main() {
  std::vector<int> v{ 3, 1, 4, 1, 5, 9 };

  std::vector<int>::iterator result = std::min_element(v.begin(), v.end());
  std::cout << "min element at: " << std::distance(v.begin(), result) << std::endl;
  // min element at: 1
  
  result = std::max_element(v.begin(), v.end());
  std::cout << "max element at: " << std::distance(v.begin(), result) << std::endl;
  // max element at: 5

  
  std::pair<
    std::vector<int>::iterator, 
    std::vector<int>::iterator> item = std::minmax_element(begin(v), end(v));

  std::cout << "min/max at: " 
    << std::distance(v.begin(), item.first) << ", "
    << std::distance(v.begin(), item.second) << std::endl;
  // min/max at: 1, 5    
}

binary_search

// 요소가 있는지 없는지만 판별에서 그렇게 좋아 보이지는 않아 보임

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

int main() {
  std::vector<int> haystack{ 1, 3, 4, 5, 9 };
  if (std::binary_search(haystack.begin(), haystack.end(), 5)) {
    std::cout << "found " << std::endl;
  } else {
    std::cout << "not found" << std::endl;
  }
}

unordered_map

#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;
int main(){
  unordered_map<string,int> um;
  if(um.empty()){
    cout<<"unordered_map은 비어있습니다"<<endl;
  }
  
  um.insert(make_pair("key",1));
  um["banana"]=2;
  um.insert({"melon",3});
  
  cout<<"unordered_map의 크기는 "<<um.size()<<" 입니다"<<endl;
  
  // auto로 해도 무방
  for(pair<string,int> elem : um){
    cout<<"key : "<<elem.first<<" value : "<<elem.second<<endl;
  }
  
  // find 대신 count로 확인 가능
  if(um.find("banana")!=um.end()){
    um.erase("banana");
  }

  um.erase(mymap.begin());// erasing by iterator
  um.erase("France");// erasing by key
  um.erase( mymap.find("China"), mymap.end() );// erasing by range  
  
  cout<<"unordered_map의 크기는 "<<um.size()<<" 입니다"<<endl;
  for(auto elem : um){
    cout<<"key : "<<elem.first<<" value : "<<elem.second<<endl;
  }
  return 0;
}

unordered_set

#include <iostream>
#include <unordered_set>
using namespace std;

int main() {
  unordered_set<int> uset;

  uset.insert(3);	// 3
  uset.insert(5);	// 3 5
  uset.insert(1);	// 3 5 1
  uset.insert(4);	// 3 5 1 4
  uset.insert(2);	// 3 5 1 4 2
  uset.insert(5); // 3 5 1 4 2
  uset.erase(4);


  uset.erase(2);

  for (int i : uset) {
    cout << i << " ";
  }
  cout << endl;
  //2 4 1 3 5 

  for (auto it = uset.find(5); it != uset.end(); it++) {
    cout << *it << " ";
  }
  cout << endl;
  //5

  unordered_multiset<int> umset;
  umset.insert(5);	// 5
  umset.insert(3);	// 5 3
  umset.insert(1);	// 5 3 1
  umset.insert(4);	// 5 3 1 4
  umset.insert(2);	// 5 3 1 4 2
  umset.insert(5);	// 5 5 3 1 4 2 
  umset.insert(1);	// 5 5 3 1 1 4 2
  umset.erase(5);

  for (int i : umset) {
    cout << i << " ";
  }
  cout << endl;
  //3 5 5 1 1 4 2 

  return 0;
}

ordered map, set

  • map, set 사용법 유사함
//정렬되어 출력 가능
#include <set>

int main() {
  set<int> s;
  s.insert(3);	// 3
  s.insert(5);	// 3 5
  s.insert(1);	// 3 5 1
  s.insert(4);	// 3 5 1 4
  s.insert(2);	// 3 5 1 4 2
  s.insert(5); // 3 5 1 4 2
  s.erase(2);
  
  for (int i : s) {
    cout << i << " ";
  }
  cout << endl;  
}

map, set erase

  • map, set 사용법 유사함
#include <map>

int main() {
  map<string,int> um;
  um.insert({"aaa",3});
  um.insert({"bbb",3});
  um.insert({"ccc",3});
  um.insert({"ddd",3});
  um.insert({"eee",3});


  um.erase(um.begin());// erasing by iterator
  for(auto elem : um){
    cout<<"key : "<<elem.first<<" value : "<<elem.second<<endl;
  }
  cout << endl;
	// key : bbb value : 3
  // key : ccc value : 3
  // key : ddd value : 3
  // key : eee value : 3
  

  um.erase("bbb");// erasing by key
  for(auto elem : um){
    cout<<"key : "<<elem.first<<" value : "<<elem.second<<endl;
  }
  cout << endl;
  // key : ccc value : 3
  // key : ddd value : 3
  // key : eee value : 3

  um.erase(um.find("ddd"), um.end());// erasing by range  
  for(auto elem : um){
    cout<<"key : "<<elem.first<<" value : "<<elem.second<<endl;
  }
  cout << endl;
  // key : ccc value : 3
}
profile
mohadang

0개의 댓글