zoukankan      html  css  js  c++  java
  • 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)
    

    原贴
    收录整理,以备复习

  • 相关阅读:
    好的文章聚集地
    java连接mysql数据库8.0以上版本过程中遇到的坑
    Tomcat8.5安装与配置的坑
    用阿里fastJson解析Json字符串
    通过java代码HttpRequestUtil(服务器端)发送HTTP请求并解析
    Vue中美元$符号的意思
    java的jdk和jre区别
    java正则
    java8 四大核心函数式接口Function、Consumer、Supplier、Predicate(转载)
    SpringBoot:静态资源的访问和配置(转载)
  • 原文地址:https://www.cnblogs.com/Forgenvueory/p/7352719.html
Copyright © 2011-2022 走看看