让V
为整数向量,让 L 为V
的长度。
现在,假设V
中不同值的 N 数小于 L EM>
还可以假设V
已排序,因此可以将其解释为 N 连续常量“块”的串联。
最后,可以假设,一旦初始化,V
此后只读(又名不可变)。
(在我正在使用的情况下, L 介于10 6 和10 7 之间, N 约为20。)
将这种低复杂度数据存储在标准MATLAB L -long向量中是浪费的。 MATLAB是否有内置的 1 数据结构
V(k)
读取其 k -th元素,使用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 当然,我知道我总是可以尝试自己实现这样的事情,但如果我能避免它,我宁愿不重新发明轮子。功能
答案 0 :(得分: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