Matlab:在向量中找到元素的第一次和最后一次出现?

时间:2015-01-29 02:00:07

标签: matlab search matrix vector

我正面临着一项不易处理的任务。

图像我有一个矢量包含4个,3个,2个三个和4个四个:

 [1,1,1,1,2,2,2,3,3,4,4,4,4]

这意味着我有1,2,3,4出现次数不同。

我想找到这些元素的第一个位置和这些元素的最终位置。这意味着我希望:

  • (1,5,8,10)为 第一次出现 (1,2,3,4)在向量中

    < / LI>
  • (4,7,9,13)为 最后一次出现 (1,2,3,4)在向量中

    < / LI>

更重要的是,如果参考向量是随机顺序而不是已排序怎么办?

我知道如何使用for循环在unique()函数的帮助下完成它。

我正在寻找更多高效,矢量化解决方案来解决这个问题。

感谢您的时间,我们将非常感谢您的帮助。

3 个答案:

答案 0 :(得分:2)

我不确定为什么不能在没有unique循环的情况下使用for。只使用第二个输出,您就可以确定要查找的内容。

鉴于你的例子:

A = [1,1,1,1,2,2,2,3,3,4,4,4,4];

如果您想要unique中每个唯一元素的第一个匹配项的索引,只需以这种方式调用A

[~,out_first,~] = unique(A, 'first');

此外,如果要查找A中每个唯一元素的最后一个匹配项的索引,请执行以下操作:

[~,out_last,~] = unique(A, 'last');

鉴于上面的例子,这是我们第一次和最后一次出现的结果:

>> out_first

out_first =

     1
     5
     8
    10

>> out_last

out_last =

     4
     7
     9
    13

如果您的向量A是随机顺序,unique仍会找到相对于A起始位置的第一个匹配项。例如,如果我改变A中的元素:

B = A(randperm(numel(A)))

>> B

B =

     2     1     4     2     3     2     1     1     1     4     3     4     4

这是我在这个混洗过的矢量上运行unique时得到的结果:

>> out_first

out_first =

     2
     1
     5
     3

>> out_last

out_last =

     9
     6
    11
    13

正如您所看到的,我们第一次遇到值1时,它位于索引2处,第一次遇到值2时,它位于索引1处,依此类推。您可以在最后一次遇到时使用相同的模式。


因此,除了对unique的单个函数调用之外,我没有看到更多的矢量化。没有必要使用for循环。

答案 1 :(得分:0)

查看以下代码和示例以及this回答:

a = [1,1,1,1,2,2,2,3,3,4,4,4,4];
first_occurences = [1, find(diff([a(1) a a(end)]))]
last_occurences = [first_occurences(2:end) - 1, length(a)]

 first_occurences =

     1     5     8    10


last_occurences =

     4     7     9    13

a = [2,2,2, 1,1,1,1,4,4,4,4, 3,3];
first_occurences = [1, find(diff([a(1) a a(end)]))]
last_occurences = [first_occurences(2:end) - 1, length(a)]


first_occurences =

     1     4     8    12


last_occurences =

     3     7    11    13


a = [4,4,4,4, 1,1,1,1, 3,3, 2,2,2];
first_occurences = [1, find(diff([a(1) a a(end)]))]
last_occurences = [first_occurences(2:end) - 1, length(a)]


first_occurences =

     1     5     9    11


last_occurences =

     4     8    10    13

答案 2 :(得分:0)

x = [1,1,1,1,2,2,2,3,3,4,4,4,4];
s = [1,2,3,4];
[valid, first] = max(bsxfun(@eq, x(:), s(:).'),[],1);
[~, last] = max(bsxfun(@eq, flipud(x(:)), s(:).'),[],1);
first(~valid) = 0;
last = numel(x)-last+1;
last(~valid) = 0;

这使用max的第二个输出返回每列中第一个最大化器的位置这一事实。此外,第一个输出用于确保每个值至少出现一次;如果不是这种情况,则将resut设置为零。例如,s = [1,2,3,4,5]的结果将是

first =
     1     5     8    10     0
last =
     4     7     9    13     0

要获取最后位置,使用相同的方法,仅使用翻转的矢量。

每个向量中的元素可以是任何顺序。