modern cpp tricks
1.0.0
이것은 코딩 인터뷰 및 경쟁 프로그래밍에 자주 사용되는 최신 CPP 트릭의 목록입니다.
Rachit의 작품을 좋아한다면 다음을 따라갈 수 있습니다.
min(x, min(y, ...))s.contains vs s.find(...) != s.endmultiset.extract vs multiset.erase(multiset.find(...)) min(x, min(y, ...)) 이니셜 라이저 목록과 std::min and std::max 사용하여 인생을 쉽게 만들 수 있습니다.
small = min(x, min(y, min(z, k))); // the old way
small = min({x, y, z, k}); // life is easy pair< int , int > cur = { 1 , 2 };
auto [x, y] = cur;
// x is now 1, y is now 2
// no need of cur.first and cur.second
array< int , 3 > arr = { 1 , 0 , - 1 };
auto [a, b, c] = arr;
// a is now 1, b is now 0, c is now -1 요점까지, 나는 종종 변수 이름과 그 값을 줄이면서 debug 매크로를 사용했습니다.
# define deb ( x ) cout << #x << " " << x
int ten = 10 ;
deb (ten); // prints "ten = 10"이것은 종종 디버깅에 유용합니다.
그러나 로그 할 여러 변수가 있으면 더 많은 deb2 및 deb3 매크로로 끝납니다.
# define deb ( x ) cout << #x << " " << x
# define deb2 ( x ) cout << #x << " " << x << " " << #y << " " << y
# define deb3 ( x, y, z ) cout << #x << " " << x << " " << #y << " " << y << " " << #z << " " << z 이것은 확장 할 수 없습니다.
다음은 Variadic 매크로 및 폴드 표현식을 사용한 솔루션입니다.
# define deb (...) logger(#__VA_ARGS__, __VA_ARGS__)
template < typename ...Args>
void logger (string vars, Args&&... values) {
cout << vars << " = " ;
string delim = " " ;
(..., (cout << delim << values, delim = " , " ));
}
int xx = 3 , yy = 10 , xxyy = 103 ;
deb (xx); // prints "xx = 3"
deb (xx, yy, xxyy); // prints "xx, yy, xxyy = 3, 10, 103" template < typename ... T>
void read (T &...args) {
((cin >> args), ...);
}
template < typename ... T>
void write (string delimiter, T &&...args) {
((cout << args << delimiter), ...);
}
template < typename T>
void readContainer (T &t) {
for ( auto &e : t) {
read (e);
}
}
template < typename T>
void writeContainer (string delimiter, T &t) {
for ( const auto &e : t) {
write (delimiter, e);
}
write ( " n " );
} // Question: read three space seprated integers and print them in different lines.
int x, y, z;
read (x, y, z);
write ( " n " , x, y, z);
// even works with variable data types :)
int n;
string s;
read (n, s);
write ( " " , s, " has length " , n, " n " );
// Question: read an array of `N` integers and print it to the output console.
int N;
read (N);
vector< int > arr (N);
readContainer (arr);
writeContainer ( " " , arr); // output: arr[0] arr[1] arr[2] ... arr[N - 1]
writeContainer ( " n " , arr);
/* *
* output:
* arr[0]
* arr[1]
* arr[2]
* ...
* ...
* ...
* arr[N - 1]
*/ template < typename ...T>
void printer (T&&... args) {
((cout << args << " " ), ...);
}
int age = 25 ;
string name = " Rachit " ;
printer ( " I am " , name, ' , ' , age, " years old " );
// ^ This prints the following
// I am Rachit, 25 years old template < typename F>
auto debug_func ( const F& func) {
return [func]( auto &&... args ) { // forward reference
cout << " input = " ;
printer (args...);
auto res = func (forward< decltype (args)>(args)...);
cout << " res = " << res << endl;
return res;
};
}
debug_func (pow)( 2 , 3 );
// ^ this automatically prints
// input = 2 3 res = 8 다른 데코레이터를 다음과 같이 beautify 정의 할 수 있습니다.
template < typename F>
auto beautify ( const F& func) {
return [func]( auto &&... args ) { // forward reference
cout << " ======== " << endl;
func (forward< decltype (args)>(args)...);
cout << " ======== " << endl;
};
}
beautify (debug_func(pow( 2 , 3 )));
// ^ this now prints
// ========
// input = 2 3 res = 8
// ======== 그런 일반적인 데코레이터를 쓰고 둥지로써 얼마나 많은 일을 할 수 있는지 놀랍습니다.
주어진 기능에 걸리는 시간을 계산하는 log_time 과 같은 데코레이터에 대해 생각해보십시오.
s.contains vs s.find(...) != s.end set<int> example{1, 2, 3, 4};
example.find(3) != example.end() // true
example.contains(3) // true
이것은 map 과 set 와 함께 작동합니다.
multiset.extract vs multiset.erase(multiset.find(...)) multiset<int> mset{1, 1, 2, 2, 3, 3};
mset.erase(1); // {2, 2, 3, 3} deleted all 1s
mset.erase(mset.find(2)) // {2, 3, 3} need to use erase + find
mset.extract(3) // {2, 3} simple and clean
multiset::extract 단일 인스턴스를 자연스럽게 제거하는 데 도움이됩니다.set 및 map 에서도 작동합니다.