• C++ Tricks


    以下内容大部分使用 C++11 !
    以下内容大部分使用 C++11 !
    以下内容大部分使用 C++11 !

    通过 {} 来给容器赋值

    pair<int, int> p;
    // ...
    p = make_pair(3, 4);
    

    其实可以这样

    pair<int, int> p;
    // ...
    p = {3, 4};
    

    对于复杂的 pair

    pair<int, pair<char, long long> > p;
    // ...
    p = {3, {'a', 8ll}};
    

    对于其他容器(vector,deque,set)

    vector<int> v;
    v = {1, 2, 5, 2};
    for (auto i: v)
        cout << i << ' ';
    cout << '
    ';
    // prints "1 2 5 2"
    
    
    deque<vector<pair<int, int>>> d;
    d = {{{3, 4}, {5, 6}}, {{1, 2}, {3, 4}}};
    for (auto i: d) {
        for (auto j: i)
            cout << j.first << ' ' << j.second << '
    ';
        cout << "-
    ";
    }
    // prints "3 4
    //         5 6
    //         -
    //	   1 2
    //	   3 4
    //	   -"
    
    
    set<int> s;
    s = {4, 6, 2, 7, 4};
    for (auto i: s)
        cout << i << ' ';
    cout << '
    ';
    // prints "2 4 6 7"
    
    
    list<int> l;
    l = {5, 6, 9, 1};
    for (auto i: l)
        cout << i << ' ';
    cout << '
    ';
    // prints "5 6 9 1"
    
    
    array<int, 4> a;
    a = {5, 8, 9, 2};
    for (auto i: a)
        cout << i << ' ';
    cout << '
    ';
    // prints "5 8 9 2"
    
    
    tuple<int, int, char> t;
    t = {3, 4, 'f'};
    cout << get<2>(t) << '
    ';
    

    注意:stack,queue不适用

    通过 '#' 来得到参数名

    #define what_is(x) cerr << #x << " is " << x << endl;
    // ...
    int a_variable = 376;
    what_is(a_variable);
    // prints "a_variable is 376"
    what_is(a_variable * 2 + 1)
    // prints "a_variable * 2 + 1 is 753"
    

    使用 <bits/stdc++.h>

    #include <bits/stdc++.h>
    

    库中自带却不怎么常用的函数

    • __gcd(value1,value2)
      e.g. __gcd(18, 27) = 9.
    • __builtin_ffs(x)
      e.g. __builtin_ffs(10) = 2 because 10 is '...10 1 0' in base 2 and first 1-bit from right is at index 1 (0-based) ’and function returns 1 + index.
    • __builtin_clz(x)
      e.g. __builtin_clz(16) = 27 because 16 is ' ... 10000'. Number of bits in a unsigned int is 32. so function returns 32 — 5 = 27.
    • __builtin_ctz(x)
      e.g. __builtin_ctz(16) = 4 because 16 is '...1 0000 '. Number of trailing 0-bits is 4.
    • __builtin_popcount(x)
      e.g. __builtin_popcount(14) = 3 because 14 is '... 111 0' and has three 1-bits.

    Note 还有其他 __bultin 函数,但是不怎么常用,cpp

    变长参数函数与宏

    int sum() { return 0; }
    
    template<typename... Args>
    int sum(int a, Args... args) { return a + sum(args...); }
    
    int main() { cout << sum(5, 7, 2, 2) + sum(3, 4); /* prints "23" */ }
    

    不止是 int

    int sum() { return 0; }
    
    template<typename T, typename... Args>
    T sum(T a, Args... args) { return a + sum(args...); }
    
    int main() { cout << sum(5, 7, 2, 2) + sum(3.14, 4.89); /* prints "24.03" */ }
    

    C++14 可以用 auto sum(T a, Args... args)

    使用宏

    #define a_macro(args...) sum(args...)
    
    int sum() { return 0; }
    
    template<typename T, typename... Args>
    auto sum(T a, Args... args) { return a + sum(args...); }
    
    int main() { cout << a_macro(5, 7, 2, 2) + a_macro(3.14, 4.89); /* prints "24.03" */ }
    

    => debug 函数

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define error(args...) { vector<string> _v = split(#args, ','); err(_v.begin(), args); }
    
    vector<string> split(const string& s, char c) {
    	vector<string> v;
    	stringstream ss(s);
    	string x;
    	while (getline(ss, x, c))
    		v.emplace_back(x);
    	return move(v);
    }
    
    void err(vector<string>::iterator it) {}
    template<typename T, typename... Args>
    void err(vector<string>::iterator it, T a, Args... args) {
    	cerr << it -> substr((*it)[0] == ' ', it -> length()) << " = " << a << '
    ';
    	err(++it, args...);
    }
    
    int main() {
    	int a = 4, b = 8, c = 9;
    	error(a, b, c);
    }
    /*
    Output:
      a = 4
      b = 8
      c = 9
    */
    

    C++0x 与 C++

    遍历

    set<int> s = {8, 2, 3, 1};
    for (set<int>::iterator it = s.begin(); it != s.end(); ++it)
        cout << *it << ' ';
    // prints "1 2 3 8"
    

    上面代码好长呀,可以这样

    set<int> s = {8, 2, 3, 1};
    for (auto it: s)
        cout << it << ' ';
    // prints "1 2 3 8"
    

    可以用 &auto 来 替代 auto

    vector<int> v = {8, 2, 3, 1};
    for (auto &it: v)  it *= 2;
    for (auto it: v)  cout << it << ' ';
    // prints "16 4 6 2"
    

    Power of auto

    set<pair<int, pair<int, int> > >::iterator
    可以这样写 auto it = s.begin()

    for(i = 1; i <= n; i++) {
        for(j = 1; j <= m; j++)
            cout << a[i][j] << " ";
        cout << "
    ";
    }
    

    等价于

    for(i = 1; i <= n; i++)
        for(j = 1; j <= m; j++)
            cout << a[i][j] << " 
    "[j == m];
    

    tie 和 emplace_back

    #define mt make_tuple
    #define eb emplace_back
    typedef tuple<int,int,int> State; // operator< defined
    
    int main(){
      int a,b,c;
      tie(a,b,c) = mt(1,2,3); // assign
      tie(a,b) = mt(b,a); // swap(a,b)
    
      vector<pair<int,int>> v;
      v.eb(a,b); // shorter and faster than pb(mp(a,b))
    
      // Dijkstra
      priority_queue<State> q;
      q.emplace(0,src,-1);
      while(q.size()){
        int dist, node, prev;
        tie(dist, ode, prev) = q.top(); q.pop();
        dist = -dist;
        // ~~ find next state ~~
        q.emplace(-new_dist, new_node, node);
      }
    }
    

    emplace_backpush_back更快,紧跟末尾比在他处快?
    tie 中可以使用 ignore 来忽略值

    tuple<int, int, int, char> t (3, 4, 5, 'g');
    int a, b;
    tie(b, ignore, a, ignore) = t;
    cout << a << ' ' << b << '
    ';
    
    /*
    Output:
      5 3
    */
    

    利用宏来循环

    #define rep(i, begin, end) for (__typeof(end) i = (begin) - ((begin) > (end)); i != (end) - ((begin) > (end)); i += 1 - 2 * ((begin) > (end)))
    
    • 不需要指明类型
    • 从 begin 到 end
    vector<int> v = {4, 5, 6, 4, 8};
    rep(it, end(v), begin(v))
        cout << *it << ' ';
    // prints "8 4 6 5 4"
    

    lambda function

    [capture list](parameters) -> return value { body }
    e.g.

    auto f = [] (int a, int b) -> int { return a + b; };
    cout << f(1, 2); // prints "3"
    

    可以在 for_each,sort等 STL 中使用

    vector<int> v = {3, 1, 2, 1, 8};
    sort(begin(v), end(v), [] (int a, int b) { return a > b; });
    for (auto i: v) cout << i << ' ';
    
    /*
    Output:
      8 3 2 1 1
    */
    

    move 的用法

    使用move 来移动容器,不需要 copy

    vector<int> v = {1, 2, 3, 4};
    vector<int> w = move(v);
    
    cout << "v: ";
    for (auto i: v)
        cout << i << ' ';
    
    cout << "
    w: ";
    for (auto i: w)
        cout << i << ' ';
    /*
    Output:
      v: 
      w: 1 2 3 4 
    */
    

    C++0x Strings

    Raw Strings

    string s = R"(Hello, World!)"; // Stored: "Hello, World!"
    A raw string skips all escape characters like 
     or ". e.g.
    
    string str = "Hello	World
    ";
    string r_str = R"(Hello	World
    )";
    cout << str << r_str;
    
    /*
    Output:
    
    Hello	World
    Hello	World
    
    */
    
    // You can also have multiple line raw string:
    
    string r_str =
    R"(Dear Programmers,
    I'm using C++11
    Regards, Swift!)";
    cout << r_str;
    
    /*
    Output:
    Dear Programmer,
    I'm using C++11
    Regards, Swift!
    */
    

    Regular Expressions (regex)

    ** e.g.** regex r = "[a-z]+";

    regex email_pattern(R"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+$)"); 
    // This email pattern is not totally correct! It's correct for most emails.
    string
    valid_email("swift@codeforces.com"),
    invalid_email("hello world");
    
    if (regex_match(valid_email, email_pattern))
        cout << valid_email << " is valid
    ";
    else
        cout << valid_email << " is invalid
    ";
    
    if (regex_match(invalid_email, email_pattern))
        cout << invalid_email << " is valid
    ";
    else
        cout << invalid_email << " is invalid
    ";
    /*
    Output:
    
    swift@codeforces.com is valid
    hello world is invalid
    */
    

    更多资料

    户定义数据标识 (User-defined literals)

    栗子 0xA,1000ll,3.14f等等

    long long operator "" _m(unsigned long long literal) {
    	return literal;
    }
    
    long double operator "" _cm(unsigned long long literal) {
    	return literal / 100.0;
    }
    
    long long operator "" _km(unsigned long long literal) {
    	return literal * 1000;
    }
    
    int main() {
    	// See results in meter:
    	cout << 250_m << " meters 
    "; // Prints 250 meters
    	cout << 12_km << " meters 
    "; // Prints 12000 meters
    	cout << 421_cm << " meters 
    "; // Prints 4.21 meters
    }
    

    Note 需要添加下划线_
    声明如下
    [returnType] operator "" _[name]([parameters]) { [body] }
    Note 参数仅能使用如下

    (const char *)
    
    (unsigned long long int)
    
    (long double)
    
    (char)
    
    (wchar_t)
    
    (char16_t)
    
    (char32_t)
    
    (const char *, size_t)
    
    (const wchar_t *, size_t)
    
    (const char16_t *, size_t)
    
    (const char32_t *, size_t)
    

    原贴
    收录整理,以备复习

  • 相关阅读:
    论文解读(GraphBert)《GraphBert: Only Attention is Needed for Learning Graph Representations》 Learner
    论文解读(SCAGC)《Selfsupervised Contrastive Attributed Graph Clustering》 Learner
    论文解读(AGE)《Adaptive Graph Encoder for Attributed Graph Embedding》 Learner
    tqdm介绍及常用方法 Learner
    论文解读(SCGC)《SCGC : SelfSupervised Contrastive Graph Clustering》 Learner
    论文解读《Strategies for Pretraining Graph Neural Networks》 Learner
    论文解读(FDGATII)《FDGATII : Fast Dynamic Graph Attention with Initial Residual and Identity Mapping》 Learner
    论文解读(GMIM)《Deep Graph Clustering via Mutual Information Maximization and Mixture Model》 Learner
    论文解读《Bilinear Graph Neural Network with Neighbor Interactions》 Learner
    AcWing 524. 愤怒的小鸟
  • 原文地址:https://www.cnblogs.com/Forgenvueory/p/7352719.html
Copyright © 2020-2023  润新知