从Matlab/Octave中的矢量中识别(并删除)序列
问题描述:
我试图从Matlab(或Octave)中的数字矢量中删除任何长度为3或更长的序列。例如,给定的矢量数据集,从Matlab/Octave中的矢量中识别(并删除)序列
dataSet = [1 2 3 7 9 11 13 17 18 19 20 22 24 25 26 28 30 31];
除去长度为3或更多的所有序列将产生prunedDataSet:
prunedDataSet = [7 9 11 13 22 28 30 31 ];
我可以蛮力一个解决方案,但我怀疑有一个更使用向量/矩阵操作简洁(也许是高效)的方法,但是我总是对产生索引或索引值的东西感到困惑。建议?
这是我想出了强制的方法:
dataSet = [1 2 3 7 9 11 13 17 18 19 20 22 24 25 26 28 30 31];
benign = [];
for i = 1:size(dataSet,2)-2;
if (dataSet(i) == (dataSet(i+1)-1) && dataSet(i) == dataSet(i+2)-2);
benign = [benign i ] ;
end;
end;
remove = [];
for i = 1:size(benign,2);
remove = [remove benign(i) benign(i)+1 benign(i)+2 ];
end;
remove = unique(remove);
prunedDataSet = setdiff(dataSet, dataSet(remove));
答
%# define dataset
dataSet = [1 2 3 7 9 11 13 17 18 19 20 22 24 25 26 28 30 31];
%# take the difference. Whatever is part of a sequence will have difference 1
dds = diff(dataSet);
%# sequences of 3 lead to two consecutive ones. Sequences of 4 are like two sequences of 3
seqIdx = findstr(dds,[1 1]);
%# remove start, start+1, start+2
dataSet(bsxfun(@plus,seqIdx,[0;1;2])) = []
dataSet =
7 9 11 13 22 28 30 31
答
下面是使用矢量矩阵符号的尝试:
s1 = [(dataSet(1:end-1) == dataSet(2:end)-1), false];
s2 = [(dataSet(1:end-2) == dataSet(3:end)-2), false, false];
s3 = s1 & s2;
s = s3 | [false, s3(1:end-1)] | [false, false, s3(1:end-2)];
dataSet(~s)
的理念是:s1
是所有职位如此,其中一些a
出现在a+1
之前。 s2
对于a
出现在a+2
之前的两个位置的所有仓位均为真。然后s
在满足前面的条件时变为真。然后,我们构建s
,以便将每个真实值传播给它的两个后继者。
最后,dataSet(~s)
保留上述条件为假的所有值,也就是说,它保留的数字不是3序列的一部分。
你需要更精确的了解你的意思是长度的_any序列有什么解决方案3个_...你的意思是只'K,K + 1,K + 2 '对于任何'k'还是可以'k,k-1,k-2'也包括在内?那么'k,±m,k±2m'或者就此而言,像k,k^2,k^3或者k,k * a,k * a^2等几何序列呢? – abcd 2011-05-28 01:02:48
对不起,我认为从dataSet/prunedDataSet明显可见,并且我给出了“暴力方法”:k,k + 1,k + 2。 – jhfrontz 2011-05-30 00:54:09
我明白你的例子。但是,不清楚的是第一行中的术语“任何序列”。无论如何,我想你在下面有很好的解决方案,所以不用担心。 – abcd 2011-05-30 00:55:59