您好,登錄后才能下訂單哦!
本文小編為大家詳細(xì)介紹“C++中vector和數(shù)組之間的轉(zhuǎn)換及其效率問(wèn)題怎么解決”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“C++中vector和數(shù)組之間的轉(zhuǎn)換及其效率問(wèn)題怎么解決”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來(lái)學(xué)習(xí)新知識(shí)吧。
眾所周知,一維vector中的元素存儲(chǔ)是順序連續(xù)的,所以我們可以通過(guò)訪問(wèn)第一個(gè)元素的地址以及元素的數(shù)量來(lái)訪問(wèn)一系列的元素。因此,我們可以采取如下操作來(lái)對(duì)vector進(jìn)行訪問(wèn)和轉(zhuǎn)換:
先創(chuàng)造一個(gè)數(shù)組
int array_size = 1000; double **array = (double **)malloc(sizeof(double *) * array_size); for (int i = 0; i < array_size; i++) array[i] = (double *)malloc(sizeof(double) * array_size); for (int i = 0; i < array_size; i++) for (int j = 0; j < array_size; j++) array[i][j] = i * array_size + j;
// method1 vector<vector<double>> t(array_size, vector<double>(array_size)); for (int i = 0; i < array_size; i++) { // 直接定義一個(gè)一維的vector,其首地址為數(shù)組的起始地址,末尾地址為最后的地址。 t[i] = vector<double>(array[i], array[i] + array_size); }
// method2 vector<vector<double>> tt(array_size, vector<double>(array_size)); for (int i = 0; i < array_size; i++) { // 直接復(fù)制每一個(gè)值 for (int j = 0; j < array_size; j++) tt[i][j] = array[i][j]; }
vector<vector<double>> ttt(array_size, vector<double>(array_size)); for (int i = 0; i < array_size; i++) { // 直接使用memcpy進(jìn)行復(fù)制 memcpy(&ttt[i][0], &array[i][0], array_size * sizeof(double)); }
對(duì)于上述的三種方法,我簡(jiǎn)單的對(duì)其進(jìn)行了效率測(cè)試,測(cè)試思路是每個(gè)都循環(huán)執(zhí)行100遍,看每個(gè)方法所需要的時(shí)間,測(cè)試代碼如下:
clock_t begin, end; double cost; begin = clock(); for (int x = 0; x < 100; x++) { vector<vector<double>> t(array_size, vector<double>(array_size)); for (int i = 0; i < array_size; i++) { t[i] = vector<double>(array[i], array[i] + array_size); } } end = clock(); cost = (double)(end - begin) / CLOCKS_PER_SEC; printf("method 1 cost: %lf secs\n", cost); // method2 begin = clock(); for (int x = 0; x < 100; x++) { vector<vector<double>> tt(array_size, vector<double>(array_size)); for (int i = 0; i < array_size; i++) { for (int j = 0; j < array_size; j++) tt[i][j] = array[i][j]; } } end = clock(); cost = (double)(end - begin) / CLOCKS_PER_SEC; printf("method 2 cost: %lf secs\n", cost); // method3 begin = clock(); for (int x = 0; x < 100; x++) { vector<vector<double>> ttt(array_size, vector<double>(array_size)); for (int i = 0; i < array_size; i++) { memcpy(&ttt[i][0], &array[i][0], array_size * sizeof(double)); } } end = clock(); cost = (double)(end - begin) / CLOCKS_PER_SEC; printf("method 3 cost: %lf secs\n", cost);
多次測(cè)試結(jié)果基本情況如下:
method 1 cost: 0.388440 secs
method 2 cost: 0.726254 secs
method 3 cost: 0.371002 secs
由此可見(jiàn),第三種方法是最快的,不過(guò)和第一種方法差距不大,第二種方法是最差的,所需時(shí)間基本是其他兩種方法的兩倍。
和數(shù)組轉(zhuǎn)換為vector的思路基本一致,因?yàn)橐痪S的數(shù)組的存儲(chǔ)也是連續(xù)隨機(jī)存儲(chǔ)的。
先創(chuàng)造一個(gè)vector:
int array_size = 1000; vector<vector<double>> v(array_size, vector<double>(array_size, 0)); for (int i = 0; i < array_size; i++) { for (int j = 0; j < array_size; j++) { v[i][j] = i * array_size + j; } }
double **array1 = (double **)malloc(sizeof(double *) * array_size); // method1 因?yàn)関ector存儲(chǔ)是順序且連續(xù)的,所以可以直接把指向數(shù)組每行首地址的地址指向vector每行的首地址 // 上面那句話有點(diǎn)繞,解釋在最后 for (int i = 0; i < array_size; i++) { array1[i] = &v[i][0]; }
double **array2 = (double **)malloc(sizeof(double *) * array_size); // method2 直接復(fù)制每一個(gè)值 for (int i = 0; i < array_size; i++) { array2[i] = (double *)malloc(sizeof(double) * array_size); for (int j = 0; j < array_size; j++) { array2[i][j] = v[i][j]; } }
double **array = (double **)malloc(sizeof(double *) * array_size); for (int i = 0; i < array_size; i++) { // method3 使用memcpy來(lái)拷貝數(shù)組的元素 array[i] = (double *)malloc(sizeof(double) * array_size); memcpy(array[i], &v[i][0], sizeof(double) * array_size); }
效率測(cè)試:因?yàn)槊總€(gè)方法的執(zhí)行都是動(dòng)態(tài)申請(qǐng)內(nèi)存,而作為程序員一定要關(guān)注內(nèi)存,所以每次malloc使用完之后需要free,但是如果按照最開(kāi)始的方法,在同一個(gè)程序內(nèi)每個(gè)執(zhí)行100遍來(lái)測(cè)試時(shí)間的話,可能會(huì)導(dǎo)致因?yàn)槌绦驁?zhí)行到最后因?yàn)閮?nèi)存使用快滿了而導(dǎo)致速度遍慢,于是,我們每個(gè)方法只是執(zhí)行1遍(因?yàn)?遍的內(nèi)存比較?。缓蟊容^時(shí)間。
測(cè)試代碼(注意,這里沒(méi)有free,在正式使用的時(shí)候要記得free):
clock_t begin, end; double cost; // method1 begin = clock(); double **array1 = (double **)malloc(sizeof(double *) * array_size); for (int i = 0; i < array_size; i++) { array1[i] = &v[i][0]; } end = clock(); cost += (double)(end - begin) / CLOCKS_PER_SEC; printf("method 1 cost: %lf secs\n", cost); // method2 begin = clock(); double **array2 = (double **)malloc(sizeof(double *) * array_size); for (int i = 0; i < array_size; i++) { array2[i] = (double *)malloc(sizeof(double) * array_size); for (int j = 0; j < array_size; j++) { array2[i][j] = v[i][j]; } } end = clock(); cost = (double)(end - begin) / CLOCKS_PER_SEC; printf("method 2 cost: %lf secs\n", cost); // method3 begin = clock(); double **array3 = (double **)malloc(sizeof(double *) * array_size); for (int i = 0; i < array_size; i++) { array3[i] = (double *)malloc(sizeof(double) * array_size); memcpy(array3[i], &v[i][0], sizeof(double) * array_size); } end = clock(); cost = (double)(end - begin) / CLOCKS_PER_SEC; printf("method 3 cost: %lf secs\n", cost);
多次測(cè)試結(jié)果大致如下:
method 1 cost: 0.000006 secs
method 2 cost: 0.007973 secs
method 3 cost: 0.003540 secs
由此可見(jiàn)第一種方法的速度最快,而且遠(yuǎn)遠(yuǎn)塊于其他兩種方法,第二種方法是第三種方法時(shí)間的兩倍。
結(jié)論,直接賦值指針?biāo)俣?gt;使用memcpy>挨個(gè)賦值。
我們可以看到在上面vector轉(zhuǎn)化為數(shù)組的中,第一種方法比其他快很多,其具體是怎么實(shí)現(xiàn)的呢,解釋如下:
二維數(shù)組的聲明有幾種方法,下面介紹其中的一種方法:
// 聲明一個(gè)指向指針的指針,有array_size個(gè)這樣的指針。 double **array = (double **)malloc(sizeof(double *) * array_size); // 每個(gè)指向指針的指針指向一個(gè)一維數(shù)組的首地址,其一維數(shù)組的長(zhǎng)度為array_size。 for (int i = 0; i < array_size; i++) array[i] = (double *)malloc(sizeof(double) * array_size);
如上圖所示,array
是指向指針的指針,其內(nèi)容為array[0]
的地址,而array[0]
的內(nèi)容為array[0][0]
的地址,array[0][0]
的內(nèi)容即為每個(gè)元素的值。
第一種方法的解釋
我們首先聲明一個(gè)指向指針的指針,其長(zhǎng)度為array_size
,也就是說(shuō),有array_size
個(gè)指針。
然后每個(gè)指針將其內(nèi)容改為每行vector的首地址,這樣就可以訪問(wèn)每個(gè)元素了。
讀到這里,這篇“C++中vector和數(shù)組之間的轉(zhuǎn)換及其效率問(wèn)題怎么解決”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識(shí)點(diǎn)還需要大家自己動(dòng)手實(shí)踐使用過(guò)才能領(lǐng)會(huì),如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。