Есть два общих метода, которые я бы рекомендовал для этого в C ++ 11 и выше, один для измерений времени компиляции и один для времени выполнения.
Используйте std::array
из std::array
, а затем используйте new
, чтобы вы могли использовать одинаковые двумерные массивы (не зубчатые).
// the alias helps cut down on the noise:
using grid = std::array sizeY>;
grid * ary = new grid;
Опять же, это работает только в том случае, если размеры измерений известны во время компиляции.
Лучший способ выполнить 2-мерный массив с размерами, известными только во время выполнения, - это превратить его в класс. Класс будет выделять 1d-массив, а затем перегрузить operator []
, чтобы обеспечить индексирование для первого измерения. Это работает, потому что в C ++ 2D-массив имеет ряд основных значений:
(Взято из http://eli.thegreenplace.net/ 2015 / memory-layout-of-multi-dimension-arrays / )
Смежная последовательность памяти хороша по соображениям производительности, а также легко очищается. Вот примерный класс, который опускает много полезных методов, но показывает основную идею:
#include
class Grid {
size_t _rows;
size_t _columns;
std::unique_ptr data;
public:
Grid(size_t rows, size_t columns)
: _rows{rows},
_columns{columns},
data{std::make_unique(rows * columns)} {}
size_t rows() const { return _rows; }
size_t columns() const { return _columns; }
int *operator[](size_t row) { return row * _columns + data.get(); }
int &operator()(size_t row, size_t column) {
return data[row * _columns + column];
}
}
Итак, мы создаем массив с std::make_unique
элементами. Мы перегружаем operator []
, который будет индексировать строку для нас. Он возвращает int *
, который указывает на начало строки, которая затем может быть разыменована как нормальная для столбца. Обратите внимание, что make_unique
сначала отправляется на C ++ 14, но при необходимости вы можете заполнить его на C ++ 11.
Также для этих типов структур также можно перегрузить operator()
:
int &operator()(size_t row, size_t column) {
return data[row * _columns + column];
}
Технически я здесь не использовал new
, но тривиально перемещаться от std::unique_ptr
до int *
и использовать new
/ delete
.
От Python FAQ:
Списки и кортежи, в то время как подобный во многих отношениях, обычно используются существенно различными способами. Кортежи могут думаться как являющийся подобным записям Паскаля или структурам C; они - небольшие коллекции связанных данных, которые могут иметь различные типы, на которых управляют как группа. Например, Декартова координата соответственно представлена как кортеж двух или трех чисел.
Списки, с другой стороны, больше похожи на массивы на других языках. Они имеют тенденцию содержать переменное количество объектов, все из которых имеют тот же тип и на которых управляют один за другим.
Обычно условно Вы не выбрали бы список или кортеж только на основе его (im) переменчивости. Вы выбрали бы кортеж для небольших коллекций совершенно других частей данных, в которых полноценный класс будет слишком тяжел, и список для наборов любого разумного размера, где у Вас есть гомогенный набор данных.
Если можно найти решение, которое работает с кортежами, используйте их, поскольку оно вызывает неизменность который вид дисков Вы вниз более функциональный путь. Вы почти никогда не сожалеете, что спустились по функциональному/неизменному пути.
Как другие упомянули, Списки и кортежи являются оба контейнерами, которые могут использоваться, чтобы хранить объекты Python. Списки расширяемы, и их содержание может измениться присвоением, с другой стороны, кортежи неизменны.
кроме того, списки не могут использоваться в качестве ключей в словаре, тогда как кортежи могут.
Каждый раз, когда я должен передать в наборе объектов к функции, если я хочу, чтобы функция не изменилась, значения передали в - я использую кортежи.
Еще, если я хочу иметь функцию для изменения значений, я использую список.
Всегда, если Вы пользуетесь внешними библиотеками и потребностью передать в списке значений к функции и не уверены в целостности данных, используйте кортеж.
Понятие кортежей очень выразительно:
Практично, они являются великими для упаковки и распаковки значений (x,y=coord
).
В сочетании со словарями (хэш-таблицы), они позволяют формы отображения, которое иначе потребовало бы многих уровней ассоциации. Например, рассмотрите маркировку, которая (x, y) была найдена.
// PHP
if (!isset($found[$x])) {
$found[$x] = Array();
$found[$x][$y] = true;
} else if (!isset($found[$x][$y])) {
$found[$x][$y] = true;
}
# Python
found[(x,y)] = True # parens added for clarity
Списки должны использоваться с ожиданием операций на его содержании (следовательно различные упоминания о неизменности). Каждый захочет вытолкать, продвинуть, соединить, резать, искать, вставить прежде, вставить после, и т.д. со списком.
Кортежи должны быть представлением низкого уровня объекта, где простые сравнения сделаны, или операции, такие как извлечение n'th элемента или n элементов предсказуемым способом, таких как пример координат, данный ранее.
Наконец, списки не hashable, таким образом, тип отображения сделанного со словарями (хэш-таблицы в Perl, ассоциативные массивы в PHP) должен быть сделан с кортежами.
Вот простой пример кортежей и словарей, вместе наконец:
"""
couple is a tuple of two people
doesLike is a dictionary mapping couples to True or False
"""
couple = "john", "jane"
doesLike = dict()
doesLike[couple] = True
doesLike["jane", "john"] = False # unrequited love :'(
Кортежи являются quick\flexible способом создать составной объект типы данных. Списки являются контейнерами для, ну, в общем, списков объектов.
, Например, Вы использовали бы Список для хранения списка студенческих деталей в классе.
Каждая студенческая деталь в том списке может быть с 3 кортежами, содержащим их число списка, имя и экзаменационную отметку.
`[(1,'Mark',86),(2,'John',34)...]`
кроме того, потому что кортежи неизменны, они могут использоваться в качестве ключей в словарях.
Список [1,2,3]
является динамичным и гибким, но та гибкость прибывает в стоимость скорости.
кортеж (1,2,3)
фиксируется (неизменный) и поэтому быстрее.