2012-01-25 2 views
2

Есть ли способ сделать этот способ создания Союза из 2 массивов A и B в C++ быстрее (с учетом любого n)? я неоспоримое мышление, но не могу видеть другую стороны ...улучшить объединение 2 массивов в C++

double *A = (double *)malloc(n*n *sizeof(double)); 
double *B = (double *)malloc( n *sizeof(double)); 
double *U = (double *)malloc((n*n+n) *sizeof(double)); 


int i=0, ci=0; 
for (i = 0; i <n*n; i++) 
    U[ci++] = A[i]; 
for (i = 0; i < n; i++) 
    U[ci++] = B[i]; 
+1

Ну, вы всегда можете использовать 'memcpy'. –

+1

У вас там нет союза. Возможно, вы должны перефразировать вопрос? –

+0

А, я вижу, вы пытаетесь создать объединение двух массивов, новый массив 'U', который содержит как' A', так и 'B'. –

ответ

7

Существует не асимптотический лучший способ сделать это, потому что вы должны скопировать каждый элемент ровно один раз. Тем не менее, вы могли бы сделать лучше с помощью операции массового копирования, как memcpy сделать работу за вас:

double *A = (double *)malloc(n*n *sizeof(double)); 
double *B = (double *)malloc( n *sizeof(double)); 
double *U = (double *)malloc((n*n+n) *sizeof(double)); 

/* Copy over A onto U. */ 
memcpy(U, A, n * n * sizeof(double)); 

/* Append B to U. */ 
memcpy((char*)U + n * n * sizeof(double), B, n * sizeof(double)); 

Это может быть быстрее, так как логика, чтобы скопировать байты через может быть вручную оптимизированы.

Вы отметили этот вопрос на C++, хотя он больше похож на код C. Тем не менее, если вы используете C++, вы могли бы написать это (используя std::copy):

double *A = new double[n * n]; 
double *B = new double[n]; 
double *U = new double[n * n + n]; 

std::copy(A, A + n * n, U); 
std::copy(B, B + n,  U + n * n); 

Или, еще лучше, используя std::vector с открытыми участками управления памятью или указатели:

vector<double> A(n * n); 
vector<double> B(n); 

vector<double> U; 
U.reserve(A.size() + B.size()); 
U.insert(U.end(), A.begin(), A.end()); 
U.insert(U.end(), B.begin(), B.end()); 

Надежда это помогает!

+0

@ ruakh- D'oh. Я должен исправлять лучше. Исправлено снова. Я думаю, 'std :: copy' и' memcpy' не работают одинаково, что довольно удивительно. – templatetypedef

+0

На самом деле, я бы хотел, чтобы избежать циклов, как вы думаете, эта std :: copy будет работать для очень больших массивов, например, 1 000 000 элементов? – cMinor

+1

@ cMinor-Yep - 'std :: copy' работает для диапазонов элементов произвольного размера. – templatetypedef

2

Поскольку вы все это конкатенации два блока памяти, вы можете использовать memcpy:

double *A = (double *)malloc(n*n *sizeof(double)); 
double *B = (double *)malloc( n *sizeof(double)); 
double *U = (double *)malloc((n*n+n) *sizeof(double)); 
memcpy(U, A, n*n *sizeof(double)); 
memcpy(U+n*n *sizeof(double), B, n *sizeof(double)); 

Если аппаратное обеспечение предоставляет одной инструкции копирования, вы можете получить некоторые улучшения производительности от него. С другой стороны, оптимизаторы могут, возможно, выяснить, что вы делаете, и заменить код на memcpy для вас.

0

Если это действительно должно быть C++, а не C, то вы должны использовать C++-конструкции, такие как std::vector.

Я считаю, что код будет выглядеть так (хотя я не проверял):

size_t n = 100; 
std::vector A(n*n); 
std::vector B(n); 
std::vector U; 

U.reserve(A.size() + B.size()); 
std::copy(A.begin(), A.end(), std::back_inserter(U)); 
std::copy(B.begin(), B.end(), std::back_inserter(U)); 

Если вы на самом деле означает союз, как в наборе союза, который не имеет повторяющихся цифр, то вам нужно сортировать и A и B, то используйте функцию std::set_union.

Смежные вопросы