zoukankan      html  css  js  c++  java
  • C++11新特性——初始化列表 initializer_list

    破事水:

      由于最近数据结构有个实验报告说是要对字符串进行排序,想偷个懒不想一个一个地赋值,虽然可以用strcpy和传入二级指针的形式直接写,但是这样感觉不美观漂亮。

      然后就去膜了一下C++11的新特性——初始化列表,概念就不说了,就讲下这东西具体怎么用吧,就是正常的写一个构造函数,然后把参数改为initializer_list<数据类型> &t

      如图所示

    可以理解为传入的参数数据被放到了一个储存器t中,利用C++11的auto可以直接遍历这个储存器t,然后把遍历到的值给结构体用。这里用的是char 数组而不是int是因为这里有一个问题,如果把initializer_list尖括号里的类型改为char *,则会报错,因为普通的""双引号代表的字符串为实际为const 类型,实际本身为一个指针,指向全局const变量中的地址,因此const char *a="123", *b="123",打印a与b的地址会发现a与b是相同的,早上就是因为这个地方百度了一会儿才明白,另外一个点就是若声明的是info数组,那么显然要用info的实例对象去初始化,因此还要把字符串加上大括号来形成一个个info实例对象

    下面是完整代码:

    #include <stdio.h>
    #include <bits/stdc++.h>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define LC(x) (x<<1)
    #define RC(x) ((x<<1)+1)
    #define MID(x,y) ((x+y)>>1)
    #define CLR(arr,val) memset(arr,val,sizeof(arr))
    #define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
    typedef pair<int, int> pii;
    typedef long long LL;
    const double PI = acos(-1.0);
    struct info
    {
    	char name[20];
    	info() {}
    	info(const initializer_list<const char *> t)
    	{
    		for (auto &item : t)
    			strcpy(name, item);
    	}
    };
    
    info one[2] = {{"this is one"}, {"this is two"}};
    int main(void)
    {
    	for (auto &it : one)
    		cout << it.name << endl;
    	return 0;
    }
    

    上面是直接用const指针进行初始化,那如果我已经有了一个字符串的二维数组像这样:char s[maxn][maxn] = {"1", "2", "3", "4"},那如何赋值呢?显然把每一个字符串的首地址的地址传进去即可。

    #include <stdio.h>
    #include <bits/stdc++.h>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define LC(x) (x<<1)
    #define RC(x) ((x<<1)+1)
    #define MID(x,y) ((x+y)>>1)
    #define CLR(arr,val) memset(arr,val,sizeof(arr))
    #define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
    typedef pair<int, int> pii;
    typedef long long LL;
    const double PI = acos(-1.0);
    const int N = 20;
    char s[N][N] = {"this is one", "this is two", "3", "4"};
    struct info
    {
    	char name[20];
    	info() {}
    	info(const initializer_list<const char *> t)
    	{
    		for (auto &item : t)
    			strcpy(name, item);
    	}
    };
    
    info one[2] = {{s[0]}, {s[1]}};
    int main(void)
    {
    	for (auto &it : one)
    		cout << it.name << endl;
    	return 0;
    }

    似乎更多的情况并不是什么用字符串赋值,而是像int、double或者自定义结构体这样的赋值,那如何从初始化列表中一个一个读取并连续地赋值到一维或更高维的数组里呢?这里用到了C++11的另一个特性,auto 类型,这样就可以方便地进入初始化列表中去

    以HDU 1005为例,如果这题用矩阵快速幂做,那么可以参考以下代码:

    #include <stdio.h>
    #include <iostream>
    using namespace std;
    const int N = 2;
    const int MOD = 7;
    const int F[3] = {0, 1, 1};
    struct Mat
    {
        int A[N][N];
        Mat()
        {
            for (int i = 0; i < N; ++i)
                for (int j = 0; j < N; ++j)
                    A[i][j] = 0;
        }
        Mat(initializer_list<int> rhs)
        {
            auto it = rhs.begin();
            for (int i = 0; it != rhs.end(); ++it, ++i)
                A[i >> 1][i & 1] = *it;
        }
        Mat operator*(const Mat &rhs)
        {
            Mat c;
            for (int i = 0; i < N; ++i)
                for (int j = 0; j < N; ++j)
                    for (int k = 0; k < N; ++k)
                        c.A[i][j] = (c.A[i][j] + A[i][k] * rhs.A[k][j]) % MOD;
            return c;
        }
        friend Mat operator^(Mat a, int b)
        {
            Mat r;
            for (int i = 0; i < N; ++i)
                r.A[i][i] = 1;
            while (b)
            {
                if (b & 1)
                    r = r * a;
                a = a * a;
                b >>= 1;
            }
            return r;
        }
    };
    int main(void)
    {
        int A, B, n;
        while (~scanf("%d%d%d", &A, &B, &n) && (A || B || n))
        {
            Mat left =
            {
                A, B,
                1, 0
            };
            Mat right =
            {
                F[2], 0,
                F[1], 0
            };
            if (n <= 2)
                printf("%d
    ", F[n]);
            else
            {
                left = left ^ (n - 2);
                Mat resultMat = left * right;
                printf("%d
    ", resultMat.A[0][0]);
            }
        }
        return 0;
    }
  • 相关阅读:
    get pc name in LAN
    study spring
    android install
    【转】Java:Session详解
    classic problem: producer and consumer
    tomcat install
    验证Monitor.PulseAll功效
    (转)Windows7的图形架构与DX的那点事
    Cannot open your default email folders. The attempt to log on to Microsoft Exchange has failed.
    Monitor.Wait初探(8)
  • 原文地址:https://www.cnblogs.com/Blackops/p/6232289.html
Copyright © 2011-2022 走看看