Многомерный массив переменных размеров в C ++ - PullRequest
4 голосов
/ 22 декабря 2009

привет, я хочу сделать что-то вроде этого:

int op(string s1, string s2){
    int x = s1.size();
    int y = s2.size();
    int matrix = new int[x][y]
    /* do stuff with matrix */
}

Почему-то я получаю следующие ошибки:

SuperString.cpp(69) : error C2540: non-constant expression as array bound
SuperString.cpp(69) : error C2440: 'initializing' : cannot convert from 'int (*)[1]' to 'int'
        This conversion requires a reinterpret_cast, a C-style cast or function-style cast
SuperString.cpp(71) : error C2109: subscript requires array or pointer type

Спасибо!

Ответы [ 6 ]

24 голосов
/ 22 декабря 2009

Вот краткое изложение того, как построить двумерный массив в C ++ с использованием различных методов.

Статическая 2D матрица:

const size_t N = 25; // the dimension of the matrix

int matrix[N][N]; // N must be known at compile-time.
// you can't change the size of N afterwards

for(size_t i = 0; i < N; ++i)
{
    for(size_t j = 0; j < N; ++j)
    {
        matrix[i][j] = /* random value! */;
    }
}

Динамическая 2d матрица:

const size_t N = 25; // the dimension of the matrix
int** matrix = new int*[N]; // each element is a pointer to an array.

for(size_t i = 0; i < N; ++i)
    matrix[i] = new int[N]; // build rows

for(size_t i = 0; i < N; ++i)
{
    for(size_t j = 0; j < N; ++j)
    {
        matrix[i][j] = /* random value! */;
    }
}

// DON'T FORGET TO DELETE THE MATRIX!
for(size_t i = 0; i < N; ++i)
    delete matrix[i];

delete matrix;

Матрица с использованием std :: vector:

// Note: This has some additional overhead
// This overhead would be eliminated once C++0x becomes main-stream ;)
// I am talking about r-value references specifically.
typedef vector< vector<int> > Matrix;
typedef vector<int> Row;

const size_t N = 25; // the dimension of the matrix
Matrix matrix;

for(size_t i = 0; i < N; ++i)
{
    Row row(N);

    for(size_t j = 0; j < N; ++j)
    {
        row[j] = /* random value! */;
    }

    matrix.push_back(row); // push each row after you fill it
}

// Once you fill the matrix, you can use it like native arrays
for(size_t i = 0; i < N; ++i)
{
    for(size_t j = 0; j < N; ++j)
    {
        cout << matrix[i][j] << " ";
    }

    cout << endl;
}

3d матрица с использованием boost :: multi_array ( взято из boost multi_array docs ):

// Note that this is much more efficient than using std::vector!
int 
main () {
  // Create a 3D array that is 3 x 4 x 2
  typedef boost::multi_array<double, 3> array_type;
  typedef array_type::index index;
  array_type A(boost::extents[3][4][2]);

  // Assign values to the elements
  int values = 0;
  for(index i = 0; i != 3; ++i) 
    for(index j = 0; j != 4; ++j)
      for(index k = 0; k != 2; ++k)
        A[i][j][k] = values++;

  // Verify values
  int verify = 0;
  for(index i = 0; i != 3; ++i) 
    for(index j = 0; j != 4; ++j)
      for(index k = 0; k != 2; ++k)
        assert(A[i][j][k] == verify++);

  return 0;
}
4 голосов
/ 22 декабря 2009

Вам необходимо объявить матрицу var как int* matrix, так как динамический массив объявлен как указатель. Но вы не можете создать двумерный массив в одном новом, так как оба измерения будут переменными. Вы можете создать одномерный массив и выполнить математическую обработку самостоятельно.
int* matrix = new int[x*y];<br> // Set element x1,y1 to 5<br> matrix[x1+y1*x] = 5;

3 голосов
/ 22 декабря 2009

Используйте boost :: multi_array . См. Документ и этот вопрос для деталей.

Это поможет вам избежать множества ошибок.

2 голосов
/ 22 декабря 2009

Если размер matrix не нужно изменять с помощью функции, вы можете объявить int s, хранящие длину string, как const. Это позволяет создавать многомерный массив, который может варьироваться по размеру для каждого вызова функции, но сохраняет постоянный размер в течение всей функции.

#include <iostream>
#include <string>

using namespace std;

int someFunc(string, string);

int someFunc(string s1, string s2)
{
    const int x = s1.length();
    const int y = s2.length();

    int matrix[x][y];
    int result=0;

    for(int i=0;i<x;i++)
        for(int j=0;j<y;j++)
            matrix[i][j]=i*j;

    for(int i=0;i<x;i++)
        for(int j=0;j<y;j++)
            result+=matrix[i][j];

    return result;
}

int main()
{
    string s1 = "fubar";
    string s2 = "somethingelse";

    cout<<someFunc(s1,s2)<<endl;
}

РЕДАКТИРОВАТЬ: При прочтении одного из других ответов, опубликованных в то время, когда я писал свой, я полагаю, вы должны использовать const size_t вместо const int. Извините, мой C ++ немного ржавый.

0 голосов
/ 22 декабря 2009

Это больше похоже на проблему синтаксиса.

Последняя проверка в gcc 4.4, int matrix[x][y];, кажется, работает как ожидалось. Если ваш массив не нуждается в изменении размера в середине функции. Вы можете попробовать этот синтаксис и посмотреть, работает ли он в вашем компиляторе.

0 голосов
/ 22 декабря 2009

Вы не можете иметь матрицу непостоянного размера строки.

Вы можете выбрать структуру "массив указателей на массивы", которую можно индексировать как pp [a] [b] как матрицу. Вы не можете выделить такую ​​структуру с одним new. Вам придется создать его вручную в буфере.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...