Melhor maneira de representar uma matriz 2-D em C ++ com o tamanho determinado no tempo de execução

StackOverflow https://stackoverflow.com/questions/256297

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.

Foi útil?

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.

boost :: multi_array

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).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top