Melhor maneira de representar uma matriz 2-D em C ++ com o tamanho determinado no tempo de execução
-
05-07-2019 - |
Pergunta
Em C ++ Eu gostaria de fazer algo como:
int n = get_int_from_user();
char* matrix = new char[n][n];
matrix[0][0] = 'c';
//...
matrix[n][n] = 'a';
delete [][] matrix;
mas é claro que isso não funciona. Qual é a melhor maneira de fazer algo semelhante? Eu vi algumas soluções para isso, mas eles parecem bastante confuso.
Solução
A maneira dinâmica manual:
Vamos dizer que você quer uma variedade de largura * altura, a forma mais eficiente é usar apenas uma matriz dimensional única:
char *matrix = new char[width*height];
Para excluí-lo:
delete[] matrix;
Para acessá-lo:
char getArrayValue(char *matrix, int row, int col)
{
return matrix[row + col*width];
}
Para modificá-lo:
void setArrayValue(char *matrix, int row, int col, char val)
{
matrix[row + col*width] = val;
}
Impulsione Matrix:
Considere o uso de boost :: matrix se você pode ter a dependência.
Você poderia, então, amarrar na aumento linear álgebra bibliotecas.
Aqui estão algumas código de exemplo de impulso: : matriz :
#include <boost/numeric/ublas/matrix.hpp>
using namespace boost::numeric::ublas;
matrix<char> m (3, 3);
for (unsigned i = 0; i < m.size1 (); ++ i)
for (unsigned j = 0; j < m.size2 (); ++ j)
m (i, j) = 3 * i + j;
na pilha para alguns compiladores:
Alguns compiladores realmente permitem que você criar matrizes na pilha com tempo de execução determinado tamanhos. g ++ é um exemplo de tal um compilador. Você não pode fazer isso por padrão VC ++ embora.
Assim, em g ++ este código é válido:
int width = 10;
int height = 10;
int matrix[width][height];
de Drew Salão mencionou que esse recurso C99 é chamado de matrizes de comprimento variável (Vlas) e provavelmente pode ser ligado em qualquer compilador moderna.
Outras dicas
Eu costumo fazer algo parecido com isto:
char *matrix = new char [width * height];
matrix[i + j * width] = 'c'; // same as matrix[i][j] = 'c';
delete [] matrix;
E sobre std::vector< std::vector<int> > array2d;
?
Você parece estar faltando o ponto inteiro de C ++ (C com classes) :-). Este é o tipo de uso que está clamando por uma classe para implementá-lo.
Você pode apenas uso STL ou outra biblioteca de classes 3o partido que eu tenho certeza que teria a estrutura de dados que você está procurando, mas, se você precisa rolar o seu próprio, basta criar uma classe com as seguintes propriedades.
- construtor que, dado n, só vai criar um novo n * n matriz de char (por exemplo, Charray) ..
- funções membro que recebem e valores definidos com base em X.Y que simplesmente se referem a Charray [x * n + y];
- destructor que apagar [] é a matriz.
Para um verdadeiro dois matriz dimensional:
int n = get_int_from_user();
char** matrix = new char*[n];
for (int i = 0; i < n; i++) {
matrix[i] = new char[n];
}
// Operations on matrix.
for (int i = 0; i < n; i++) {
delete [] matrix[i];
}
delete matrix;
Apenas fora do topo da minha cabeça. Erros, sem dúvida. No entanto, outras pessoas postaram uma abordagem mais elegante, eu acho.
fazê-lo com a mão vai ser uma bagunça.
Eu gosto da abordagem gama 1-d (a resposta selecionada por Brian R. Bondy) com a extensão que envolva os membros de dados em uma classe de modo que você não precisa manter o controle da largura separadamente:
class Matrix
{
int width;
int height;
char* data;
public:
Matrix();
Matrix(int width, int height);
~Matrix();
char getArrayValue(int row, int col);
void setArrayValue(int row, int col, char val);
}
A implementação é um exercício para o leitor. ;)
Eu acho que isso seria uma boa.
int n = get_int_from_user();
char **matrix=new (char*)[n];
for(int i=0;i<n;i++)
matrix[i]=new char[n];
matrix[0][0] = 'c';
//...
matrix[n][n] = 'a';
for(int i=0;i<n;i++)
delete []matrix;
delete []matrix;
std::vector<int> m;
Em seguida, chamar m.resize () em tempo de execução.
int* matrix = new int[w*h];
Se você quer fazer algo como eliminação de Gauss sua matriz deve ser
int** matrix = new int*[h];
for(size_t i(0); i < h; ++i)
matrix[i] = new int[w];
(em eliminação de Gauss que geralmente precisam trocar uma linha com outro, por isso é melhor para ponteiros de swap para linhas em tempo constante, em vez de trocar copiando em tempo linear).