W moim kodzie mam macierz podwójnego podobnego do tego:

double * * matrix=new double * [10];
for(int i=0;i<10;i++) 
    matrix[i]=new double[10];

Chcę mieć wartość nan w każdej komórce tej matrycy, gdy zainicjowałem go, czy można zrobić automatycznie lub jedynym rozwiązaniem jest:

for(int i=0;i<10;i++)
    for(int j=0;j<10;j++)
        matrix[i][j]=nan("");

Czy to możliwe, aby wywnioskować, że gdy matryca będzie kupować, nie używa domyślnego konstruktora podwójnego, który wkłada, dla każdej matrycy [I] [J], 0,0 Value, ale wstaw nan ("")?

2
Antonio1996 2 czerwiec 2018, 21:23

3 odpowiedzi

Najlepsza odpowiedź

double nie ma domyślnego konstruktora, tj. Wartości {X1}} są domyślnie niezainicjowane.

Aby uniknąć wyraźnego wdrażania pętli, możesz użyć std::vector:

#include <vector>
...
std::vector<std::vector<double>> matrix(10, std::vector<double>(10, nan("")));

Lub:

#include <vector>
using namespace std;
...
vector<vector<double>> matrix(10, vector<double>(10, nan("")));
2
Sid S 2 czerwiec 2018, 20:40

Najpierw Silnie unikaj za pomocą surowych wskazówek w C ++ sam - prawie zawsze jest zły pomysł. Jeśli nie ma klasy kontenerowej, która pasuje, użyj std::unique_ptr. Więc twój kod staje się:

auto matrix = std::make_unique<double* []>(10);
for(int i=0;i<10;i++)  {
    matrix.get()[i]= std::make_unique<double []>(10);
}

Ten kod nadal nie jest tym, czego chcesz. Zwykle nie jest to dobry pomysł, aby utworzyć matrycę NXN za pomocą N W rozmowach do new lub N Wykonaj pojedynczy alokacja NXN podwójnych, a następnie owij się go w klasie MyMatrix, która obsługuje 2-parametrowy operator kwadratowy, tj.

template <typename T>
class MyMatrix { 
   // etc. etc
   double const T& operator[](size_type i, size_type j) const { return data_[i*n + j]; }
   double T& operator[](size_type i, size_type j) { return data_[i*n + j]; }
}

Lub (nie zalecane) mają wskaźnik do regionu pojedynczego alokacji:

size_t n = 10;
auto matrix_data = std::make_unique<double []>(n * n);
auto matrix = std::make_unique<double* []>(n);
for(int i=0;i<10;i++)  {
    matrix.get()[i] = matrix_data.get() + i * n;
}

W każdym z tych przypadków możesz później używać std::fill, aby ustawić wszystkie wartości matrycy na NAN, poza każdą pętlę.

Ostatnim przykładem można również przekształcić w stosowanie wektory (prawdopodobnie jest lepszym pomysłem niż tylko surowe wskaźniki, jeśli nie używasz własnej klasy):

size_t n = 10;
auto matrix_data = std::vector<double>(n * n);
auto matrix = std::vector<double*>(n);
for(auto& row : matrix) {
    auto row_index = std::dist(row, matrix.begin());
    row = &matrix_data[row_index * n];
}

Ponownie, nie polecam tego - nadal jest to sposób, aby włączyć składnię my_matrix[i][j], podczas gdy za pomocą klas opakowania dostaje my_matrix[i,j] bez konieczności dodatkowego przechowywania, z inicjalizacją do NAN lub innej wartości (W konstruktorze) i bez dwóch wskazówek za każdym razem, gdy go masz dostęp.

1
einpoklum 2 czerwiec 2018, 23:17

Jeśli chcesz użyć tablic wielkości statycznie, lepiej byłbyś używać przy użyciu std::array. Aby ułatwić korzystanie z multi-dimenstional std::array można użyć aliasu szablonu

template <class T, size_t ROW, size_t COL>
using Matrix = std::array<std::array<T, COL>, ROW>;

Możesz ustawić wartości w matrycy z std::array::fill, np.

Matrix<double, 3, 4> m = {};
m.fill(42.0);

Możesz również utworzyć obiekt stały stały obiekt matrycowy kompilacji zainicjowany z wartością domyślną, aby pominąć inicjalizację w czasie wykonywania z prostym constexpr.

template<typename T, size_t R, size_t C>
constexpr auto makeArray(T&& x) {
    Matrix<T,R,C> m = {};
    for(size_t i=0; i != R; ++i) {
        for(size_t j=0; j != C; ++j) {
            m[i][j] = std::forward<T>(x);
        }
    }
    return m;
}

auto constexpr m = makeArray<double, 3,4>(23.42);

Zamierzam powtórzyć radę, którą preferuje konstruowanie C ++ na konstru budowlanych. Są one bardziej bezpieczne, a Imho prawie zawsze wygodniejsze w użyciu, np. Przekazywanie std::array obiekty jako parametry nie różni się od innych obiektów. Jeśli pochodzisz z tła C i nie ma dalszych doświadczeń C ++, polecam przeczytać jakiś tekst samouczka, który nie wprowadza najpierw C, np. Wycieczka po C ++,

0
Jens 2 czerwiec 2018, 21:33