Как сделать многомерный массив из обычного массива в C ++

0

Если бы у меня был массив let, то для меня было бы 15 элементов, чтобы сделать его 2-мерным массивом с 5x3? Или, если бы у меня была строка с 15 буквами, можно было бы превратить ее в массив 2d с 5x3?

Это то, что у меня есть (используя переменные, но используя 5 как a и 3 как b в консоли)

    void finishMap(string map, int a, int b)
{
    string finalMap[a][b];
    for(int i = 0; b>i; i++)
    {
        for(int x = 0; a>x; x++)
        {
            finalMap[a][b] += {{map[x]}, {i}};
        }
    }
}

Также довольно новый для c++, поэтому, если вы видите что-то, что мне не должно быть, скажите мне: 3

  • 0
    Массивы в стиле C должны иметь размерность, известную во время компиляции в C ++; вы не можете использовать string finalMap[a][b];
  • 0
    @MattMcNabb вы можете перейти на string finalMap[a][b]; но на самом деле это не делает то, что он думает.
Показать ещё 2 комментария
Теги:
arrays
multidimensional-array

4 ответа

0
Лучший ответ

Я использую char arrays (c строк) в своем ответе, потому что я думаю, что они полезны, чтобы проиллюстрировать работу массивов - и действительно, не стоит использовать std :: string в вашем случае. std::string скрывает много базовых гаек и болтов, поэтому я бы рекомендовал сначала поиграть со строками C, чтобы понять, как работает std::string. Также ознакомьтесь с этим руководством: http://www.cplusplus.com/doc/tutorial/arrays/

2-мерный массив имеет тот же макет памяти, что и 1-й массив. Что касается макета памяти, char[3][5] совпадает с char[3*5], то такой же, как char[15]. Вы можете использовать 1-й массив как 2-мерный массив, используя char[column+row*width]. Единственная разница, если вы используете индексы, заключается в том, что компилятор запоминает, сколько измерений существует и будет выполнять весь расчет column+row*width для вас.

Возьмем следующий пример:

char temp[5] = "abcd"; //need 5 for string termination char '\0'

for(int i = 0; i < 4; ++i) {
    std::cout << temp[i];
}        
std::cout << "\n\n";

for(int i = 0; i < 2; ++i) {
    for(int j = 0; j < 2; ++j) {
        std::cout << temp[j+2*i];
    }
    std::cout << std::endl;
}

Будет печать:

abcd

ab
cd
  • 0
    на самом деле не помогает мне с точки зрения создания многомерного массива ... я предполагаю, что наложение карты хранится в 2d массиве ...
  • 0
    Сделал то, что я спросил в оригинальном вопросе, спасибо :)
0

Okey, поэтому я использовал что-то немного отличное от того, что я упомянул. Я сделал, чтобы пользователь вводил 3 строки из 5 букв длины, которые я выяснил, как добавить в массив 2d. Если у вас такая же проблема, как и у меня, мой код:

int main()
{
    string path;
    int a, b;
    cin >> a >> b;
    string finalMap[a][b];

    for(int i = 0; b>i; i++){
        cin >> path;
        for(int x = 0; a>x; x++){
            finalMap[x][i] = (path[x]);
        }
    }

    for(int x = 0; b>x; x++)
    {
        for(int y = 0; a>y; y++)
        {
            cout << finalMap[y][x];
        }
        cout << endl;
    }
    return 0;
}

Спасибо, что попробовали, действительно ценю это.

  • 0
    Обратите внимание, что выражение finalMap[x][i] оценивается аналогично finalMap[x*b + i] , что означает, что вы обращаетесь к массиву столбец за столбцом. Современному оборудованию это не нравится, это может означать много дополнительных кеш-пропусков, что может привести к значительному снижению производительности. Поэтому рекомендуется поменять порядок координат: замените finalMap[a][b] на finalMap[b][a] и проделайте то же самое с двумя другими строками, которые обращаются к finalMap .
  • 0
    Спасибо, ценю это.
Показать ещё 4 комментария
0

Вы можете попробовать использовать reinterpret_cast. Полный пример:

#include <iostream>

using namespace std;

typedef char mtrx[5][3];

int main(){
   char data[15] = "Some String";
   mtrx &m = *reinterpret_cast<mtrx*>(&data);
   m[1][2] = '*';
   cout << data << endl;
   return 0;
}
  • 0
    Как бы я добавить вещи в массив 2d?
  • 0
    @ 3rdaccountQQ если я правильно понимаю вопрос, вы можете изменить содержимое data или m ( data[5]='x' совпадает с m[1][2]='x' ), они оба ссылаются на одну и ту же память Только не выходи за пределы досягаемости.
0

Вы всегда можете получить доступ к массиву в шагах. Вот возможный пример использования шаблонов для ограничения массива 1D как 2D-массив:

template <typename T, unsigned int N1, unsigned int N2>
struct strider
{
    using array_type = T[N1 * N2];

    array_type & data_;

    Strider(array_type & data) : data_(data) {}

    T & operator()(std::size_t i1, std::size_t i2)
    {
        return data_[i1 * N2 + i2];
    }
};

template <unsigned int N1, unsigned int N2, T>
strider<T, N1, N2> stride(T (&a)[N1, N2]) { return {a}; }

Применение:

int a[15] = {};

strider<int, 3, 5> s(a);
s(1, 2) = 20;
assert(a[7] == 20);

stride<5, 3>(a)(4, 2) = 10;
assert(a[14] == 10);

Я перегрузил operator() для плавного доступа, так как в отличие от operator[] он может иметь подписи arbirary.

С некоторой дополнительной работой вы можете сделать ранг чередующегося вида вариативным.

  • 0
    Я не понимаю, как это будет работать с переменными

Ещё вопросы

Сообщество Overcoder
Наверх
Меню