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\n", F[n]);
        else
        {
            left = left ^ (n - 2);
            Mat resultMat = left * right;
            printf("%d\n", resultMat.A[0][0]);
        }
    }
    return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM