Как правило, правильным ответом для этого является массив ячеек. Это самый простой случай. В некоторых примерах используется:
%Writes
X = {[1], [1 2 3], [1 2]};
X{4} = [1 2 3 4];
%Reads
a = X{1}
b = cat(2,X{:});
c = X([2 4]);
Однако это не единственный ответ.
Вы можете использовать массив структур, каждая из которых имеет поле с именем .indexes
(или подходящее имя в зависимости от вашей проблемы). Это дает немного больше гибкости, если есть дополнительная информация, которую вы хотели бы прикрепить к вашему списку списков, например, позиция куба может быть добавлена как поле .position
. Пример использования:
%Writes
X(1).indexes = 1;
X(2).indexes = [1 2 3];
X(3).indexes = [1 2];
%Reads
a = X(1).indexes
b = cat(2,X.indexes)
c = X([2 4]);
Вы также можете использовать объект containers.Map. Это имеет те же преимущества, что и массив структур, но с большей гибкостью в том, как вы ссылаетесь на свои объекты. В то время как при использовании массива структур структура является ссылкой по индексу, использование объекта container.Map может ссылаться на каждую структуру, используя произвольное число (не целые числа около 1) или имя (непрактично для случаев 2 ^ 24). Это, вероятно, не лучший ответ для вас, но для справки примеры использования приведены ниже:
%Writes
X = containers.Map('keyType','uint32','valueType','Any');
X(1) = [1];
X(2) = [1 2 3];
X(3) = [1 2];
X(4) = [1 2 3 4];
%Reads
a = X(1);
b = cat(2,X.values);
Наконец, возможно, стоит определить для этого пару пользовательских классов. Это немного больше работы по настройке, но это, вероятно, самый простой способ получить постоянное время поиска в ваших предварительно вычисленных значениях. Некоторый код, который поможет вам начать этот путь, приведен ниже.
%A start at cube.m. Most of the code handles smartly reallocating the list of lines.
classdef cube < handle
properties (SetAccess = private, GetAccess = public)
numLines = 0
intersectingLines = [];
end
methods (Access = public)
function addLine(self, lineToAdd)
if self.numLines == 0
self.intersectingLines = lineToAdd;
self.numLines = 1;
elseif self.numLines>=length(self.intersectingLines)
self.intersectingLines(length(self.intersectingLines)*2) = line();
self.intersectingLines(self.numLines+1) = lineToAdd;
self.numLines = self.numLines+1;
else
self.intersectingLines(self.numLines+1) = lineToAdd;
self.numLines = self.numLines+1;
end
end
end
end
%A start at line.m. A near copy/paste of cube.m
classdef line < handle
properties (SetAccess = private, GetAccess = public)
numCubes = 0
intersectingCubes = [];
end
methods (Access = public)
function addCube(self, cubeToAdd)
if self.numCubes == 0
self.intersectingCubes = cubeToAdd;
self.numCubes = 1;
elseif self.numCubes>=length(self.intersectingCubes)
self.intersectingCubes(length(self.intersectingCubes)*2) = cube();
self.intersectingCubes(self.numCubes+1) = cubeToAdd;
self.numCubes = self.numCubes+1;
else
self.intersectingCubes(self.numCubes+1) = cubeToAdd;
self.numCubes = self.numCubes+1;
end
end
end
end
Чтобы использовать эти классы в том виде, в котором они написаны, вам нужно вызывать add
методов парами (очевидным обновлением на будущее является правильное перекрестное добавление. Тем временем (потому что я ленивый) мы определим вспомогательную функцию.
function crossAdd(cube, line)
cube.addLine(line);
line.addCube(cube);
Теперь пример использования:
%Create two class arrays of cubes and lines
allCubes(1) = cube;
allCubes(2) = cube;
allCubes(3) = cube;
allCubes(4) = cube;
allLines(1) = line;
allLines(2) = line;
allLines(3) = line;
allLines(4) = line;
%Define links (matching above "writes" examples)
crossAdd(allCubes(1), allLines(1));
crossAdd(allCubes(2), allLines(1));
crossAdd(allCubes(2), allLines(2));
crossAdd(allCubes(2), allLines(3));
crossAdd(allCubes(3), allLines(1));
crossAdd(allCubes(3), allLines(2));
crossAdd(allCubes(4), allLines(1));
crossAdd(allCubes(4), allLines(2));
crossAdd(allCubes(4), allLines(3));
crossAdd(allCubes(4), allLines(4));
%Use linked values
aLines = allCubes(1).getLines %Only one intersecting line
bLines = allCubes(2).getLines %Three intersecting lines
cubesFromSecondLine = bLines(2).getCubes %Three cubes here (2, 3, 4)
Кстати, на самом деле мы просто используем тот факт, что < handle
классов ведут себя как передача по ссылке, поэтому мы можем использовать сложные структуры данных с перекрестными ссылками.
07.12.2012