Matlab 低复杂度整数向量的有效表示
设Matlab 低复杂度整数向量的有效表示,matlab,Matlab,设V为整数向量,L为V的长度 现在,假设V中不同值的数量N远小于L 还可以假设V已排序,因此可以将其解释为N个连续常量“块”的串联 最后,我们可以假设,一旦初始化,V从此是只读的(也称为不可变的) (在我目前使用的例子中,L在106到107之间,N大约是20。) 将这种低复杂度的数据存储在标准的MATLAB L-长向量中是浪费的。MATLAB是否有任何内置的数据结构 与正则向量具有相同的接口(例如,可以使用表达式V(k)读取其第k个元素,使用V(end)读取其最后一个元素,使用V(p:q)读取位
V
为整数向量,L为V
的长度
现在,假设V
中不同值的数量N远小于L
还可以假设V
已排序,因此可以将其解释为N个连续常量“块”的串联
最后,我们可以假设,一旦初始化,V
从此是只读的(也称为不可变的)
(在我目前使用的例子中,L在106到107之间,N大约是20。)
将这种低复杂度的数据存储在标准的MATLAB L-长向量中是浪费的。MATLAB是否有任何内置的数据结构
V(k)
读取其第k个元素,使用V(end)
读取其最后一个元素,使用V(p:q)
读取位置范围等)顺便说一句,这里的问题让人想起稀疏数组表示,但不完全相同(至少是AFAICT)
好的,这是我的解决方案,基于gariepy的回答:
block_sizes = [5, 4, 3, 2];
block_values = 1000 + (1:numel(block_sizes));
interpolation_table = [0 cumsum(block_sizes)];
V = @(i) interp1(interpolation_table, [NaN block_values], i, 'next');
V(0)
ans =
NaN
V(1:5)
ans =
1001 1001 1001 1001 1001
V(6:9)
ans =
1002 1002 1002 1002
V(10:12)
ans =
1003 1003 1003
V(13:14)
ans =
1004 1004
V(15)
ans =
NaN
但它有一个小小的疣子:
V(end)
ans =
1001
(如果它在给定end
作为参数时引发异常,而不是给出完全疯狂的答案,那会更好。)
1当然,我知道我总是可以尝试自己实现这样的东西,但如果可以避免的话,我宁愿不重新发明轮子。表示此数据的一种可能方法是插值表 假设
vec
是长度L向量。首先,计算出现的次数:
[num_occurrences, y_values] = hist(vec, unique(vec));
然后,构建插值表示:
interp_table = zeros(1,length(y_values) + 1);
interp_table(1) = 1;
y_values(end+1) = y_values(end) + 1; % Need to create a "fake" value at the end of the interpolation table
for i = 2:length(y_values)
interp_table(i) = interp_table(i-1) + num_occurrences(i-1);
end
最后,定义一个函数句柄,为您提供所需的“类似数组”的访问
my_fun = @(x) interp1(interp_table, y_values, x, 'previous');
例如:
>> vec = [1 1 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 ];
>> my_fun(1)
ans =
1
>> my_fun(2)
ans =
1
>> my_fun(3)
ans =
2
>> my_fun(6)
ans =
2
>> my_fun(7)
ans =
2
>> my_fun(8)
ans =
3
>> my_fun(17)
ans =
3
>> my_fun(18) %% This is vec(L+1), so it should never be needed
ans =
4
>> my_fun(19) %% Above index L+1, values are not defined
ans =
NaN
示例演示了一个小警告:不应使用my_fun(L)以上的值,其中L是由插值表表示的原始向量的长度。因此,这提供了类似于数组的访问,尽管不能直接计算插值表的“长度”
编辑:请注意,您可以使用此插值函数进行范围编辑:
>> my_fun(1:17)
ans =
Columns 1 through 15
1 1 2 2 2 2 2 3 3 3 3 3 3 3 3
Columns 16 through 17
3 3
简短的回答是否定的。不过,根据您使用该向量的方式,可能有一种方法可以实现您想要的,而无需将整个向量存储在内存中。如果你给我们举一个用例的例子,也许我们能帮上忙。@Suever:我已经举了一个例子:L=100万,N=20。这些是问题中唯一的参数。对,但是你的目标只是创建这个向量,还是你想用这个向量做点什么。如果只是为了创建它,那么您需要推出自己的实现。如果你想做某事,那么可能有一种内在的方式。@Suever:现在我明白你的意思了。不,我在寻找一般的数据结构。我想答案是“不”。这就差不多解决了。谢谢,好主意。我把它改了一点。请参阅我的编辑。