2016-03-25 10 views
9

Ich habe versucht, zweidimensionales Array in ein anderes Array mit einer anderen Größe zu kopieren. Zum Beispiel: erster Array mit 4 Reihen und 4 Spalten:Kopieren Sie zweidimensionale Array-Elemente in ein anderes zweidimensionales Array mit einer anderen Größe

1 2 3 4 
5 6 7 8 
9 0 1 2 
3 4 5 6 

zweiter Array mit 2 Reihen und 8 Spalten:

1 2 3 4 5 6 7 8 
9 0 1 2 3 4 5 6 

und wenn es in dem neuen Array mehr Elemente als erstes ist dann wird die Funktion es mit 0

füllen, das ist die Funktion, die ich gemacht habe, aber das Problem mit Indizes. Wie schreibe ich es richtig?

void changearr(int **ppm, int size1, int size2, int size_1, int size_2) 
{ 
    int **temp = new int*[size_1]; 
    for (int i = 0; i < size_1; i++) 
     temp[i] = new int[size_2]; 
    int z = 0; 
    for (int i = 0; i < size_1; i++, z++) 
    { 
     for (int j = 0, k = 0; j < size_2; j++, k++) 
     { 
      if (i < size_1 || j < size_2) 
      { 
       temp[i][j] = ppm[z][k]; 
      } 
      else 
       temp[i][j] = 0 
     } 
    } 
+0

nur Schleife auf das erste Array mit i und j. Die Indizes z und k für das zweite Array müssen von i und j ausgewertet werden, nicht über z und k. –

+0

Da ein Array zusammenhängend im Speicher ist, sind die Arrays in der Art, in der sie gespeichert sind, fast identisch. Die Frage ist, welche Überprüfungsebene Sie in Ihrer Funktion benötigen. Was möchten Sie unter der Bedingung, dass das Ziel kleiner als die Quelle ist? Und wie bereits erwähnt, muss es nur für Arrays oder auch für ein Array von Zeigern ausgeführt werden? Wenn die Daten im Speicher zusammenhängen, können Sie dies in ein oder zwei Zeilen tun. – Chiel

Antwort

7

Warum nicht eine temporäre lineare Anordnung von der Eingangsmatrix zu machen und dann verwenden, um die Ausgangsmatrix zu füllen:

void changearr (int** ppm, int old_row, int old_col, int new_row, int new_col) 
{ 
    int* temp_linear = new int[old_row * old_col]; 

    int k = 0; 
    for (int i = 0; i < old_row; i++) 
    { 
     for (int j = 0; j < old_col; j++) 
     { 
      temp_linear[k++] = ppm[i][j]; 
     } 
    } 

    int** temp = new int* [new_row]; 
    for (int i = 0; i < new_row; i++) 
    { 
     temp[i] = new int[new_col]; 
    } 

    k = 0; 
    for (int i = 0; i < new_row; i++) 
    { 
     for (int j = 0; j < new_col; j++) 
     { 
      if (k < old_row * old_col) 
      { 
       temp[i][j] = temp_linear[k++]; 
      } 
      else 
      { 
       temp[i][j] = 0; 
      } 
     } 
    } 
} 
8

Ohhhhh, was für ein schönes Programmierpuzzle. Meine Lösung besteht darin, beide Arrays zu glätten und sie zu kopieren.

template <typename T> 
static constexpr T* begin(T& value) noexcept 
{ 
    return &value; 
} 

template <typename T, ::std::size_t N> 
static constexpr typename ::std::remove_all_extents<T>::type* 
begin(T (&array)[N]) noexcept 
{ 
    return begin(*array); 
} 

template <typename T> 
static constexpr T* end(T& value) noexcept 
{ 
    return &value + 1; 
} 

template <typename T, ::std::size_t N> 
static constexpr typename ::std::remove_all_extents<T>::type* 
end(T (&array)[N]) noexcept 
{ 
    return end(array[N - 1]); 
} 

int a[4][4]; 
int b[2][8]; 

::std::copy(begin(a), end(a), begin(b)); 
+0

Das sind 8 Zeilen und 2 Spalten;) – xinaiz

+0

Diese Lösung würde im OP-Beispiel nicht funktionieren, wo er einen Zeiger hat, kein Array, und Ihre Lösung beruht auf der Kenntnis der Array-Größe zur Kompilierzeit. – LoPiTaL

6

Sie einfach temporäre Container verwenden:

#include <iostream> 
#include <deque> 
#include <array> 

int main() 
{ 
    std::array<std::array<int,4>,4> first {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; //4x4 
    std::array<std::array<int,8>,2> second; //2x8 
    std::deque<int> temp; //temporary container 

    for(auto x : first) 
     for(auto y : x) 
      temp.push_back(y); //push everything from first to deque 

    for(auto& x : second) 
     for(auto& y : x) 
     { 
      y = temp.front(); //move from deque to second and pop() 
      temp.pop_front(); 
     } 
} 
3

Wie Sie wissen, haben C/C++ n-dimensionale Arrays eine lineare Repräsentation im Speicher. Also, wenn Sie auf einer solchen Darstellung wechseln erhalten Sie folgende Vorteile erhalten:

std::vector<int> v1{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; 
for(size_t r = 0; r < 4; r++) 
for(size_t c = 0; c < 4; c++) 
    std::cout << v1[r*4+c]; 
std::vector<int> v2(v1); 
for(size_t r = 0; r < 2; r++) 
for(size_t c = 0; c < 8; c++) 
    std::cout << v2[r*8+c]; 
4

Ein 2D-Array ist nicht die gleiche Sache ein Zeiger auf Zeiger ist! Als ein 2D-Array nacheinander einfach die Reihen zu speichern, müssen Sie nur Elemente kopieren:

#include <iostream> 

void trans(int* orig, int rows1, int cols1, int *resul, int rows2, int cols2) { 
    int tot1 = rows1 * cols1; 
    int tot2 = rows2 * cols2; 
    int tot = tot1; 
    if (tot2 < tot) tot = tot2; 
    // copy the smallest size from both arrays 
    for(int i=0; i<tot; i++) { 
     resul[i] = orig[i]; 
    } 
    // eventually add 0 to fill resul array 
    for(int i=tot; i<tot2; i++) { 
     resul[i] = 0; 
    } 
} 
int main() 
{ 
    int orig[4][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6}; 
    // control initial array 
    for (int i=0; i<4; i++) { 
     for (int j=0; j<4; j++) { 
      std::cout << orig[i][j]; 
     } 
     std::cout << std::endl; 
    } 
    int resul[2][8]; 
    // pass arrays as 1D array pointers! 
    trans(reinterpret_cast<int *>(&orig), 4, 4, reinterpret_cast<int *>(&resul), 2, 8); 
    // control converted array 
    for (int i=0; i<2; i++) { 
     for (int j=0; j<8; j++) { 
      std::cout << resul[i][j]; 
     } 
     std::cout << std::endl; 
    } 
    return 0; 
} 

Es erwartet gibt:

1234 
5678 
9012 
3456 
12345678 
9
3

Hier ist eine ziemlich einfache Art und Weise ist:

void 
    changearr(
    int **in,int in_size1,int in_size2, 
    int **out,int out_size1,int out_size2 
    ) 
{ 
    int in_n = in_size1*in_size2; 
    int out_n = out_size1*out_size2; 
    int n = min(in_n,out_n); 
    int i = 0; 

    for (; i!=n; ++i) { 
    out[i/out_size2][i%out_size2] = in[i/in_size2][i%in_size2]; 
    } 

    for (; i!=out_n; ++i) { 
    out[i/out_size2][i%out_size2] = 0; 
    } 
} 

Die Idee besteht nur darin, die Indizes linear zu durchlaufen und die entsprechenden Indizes für die Eingabe- und Ausgabearrays nach Bedarf zu berechnen.

Verwandte Themen