首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Matlab中存储这种结构(整数列表)?

如何在Matlab中存储这种结构(整数列表)?
EN

Stack Overflow用户
提问于 2012-12-07 15:56:05
回答 1查看 7.1K关注 0票数 3

我需要存储一个整数列表。例如,X[1]应该能够包含[1 3 5],而X[2]可以包含[1 2]。什么是最好的解决方案?细胞阵列?

背后的故事:

对于一个项目,我预先计算了N行和M立方体之间的交点.检索这些数据的方式有两种:给定一个行索引,我想要一个它通过的多维数据集列表,以及一个多维数据集索引,我想要一个通过它的行列表。

典型的值是N=2^24和M=2^18,这意味着不可能有一个交集矩阵(NxM)。幸运的是,平均线只通过M^(1/3)=2^6立方体。目前,我将结构存储为NxM^(1/3)矩阵,因此X(n,:)是第n行通过的立方体向量(填充为零)。

这对于检索给定列表索引的多维数据集很好,但事实证明,我代码的瓶颈是检索给定多维数据集索引的行。(我使用的是find(X==m),其中m是多维数据集索引。)我不能创建相反的矩阵,因为通过单个立方体的行数可能很高,尽管它的平均值很低。

EN

回答 1

Stack Overflow用户

发布于 2012-12-07 16:15:40

通常,单元格数组是正确的答案。这是最简单的例子。一些例子使用:

代码语言:javascript
复制
%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字段,则这允许更多的灵活性。示例使用:

代码语言:javascript
复制
%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对象。这与结构数组具有相同的优点,但在如何引用对象方面具有更大的灵活性。而当使用结构的数组是通过索引引用结构时,使用containers.Map对象可以使用任意数字(不是1附近的整数)或名称(对于2^24种情况不实用)来引用每个结构。这可能不是对您最好的答案,但对于参考示例,如下所示:

代码语言:javascript
复制
%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);

最后,为此定义一对自定义类可能是值得的。这是一些更多的工作设置,但可能是最简单的方式,以获得恒定的时间查找您的预先计算的值。下面是一些让您开始沿着这条路径前进的代码。

代码语言:javascript
复制
%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方法(后面的一个明显的升级是正确交叉添加)。同时(因为我很懒),我们将定义一个助手函数。

代码语言:javascript
复制
function crossAdd(cube, line)
cube.addLine(line);
line.addCube(cube);

现在,示例用法是:

代码语言:javascript
复制
%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类是按引用传递的,所以我们可以使用复杂的、交叉链接的数据结构。

票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13766523

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档