计算数组中的重复整数

时间:2019-01-07 18:08:27

标签: matlab sorting vector sequence counting

如果我有这个向量:

x = [1 1 1 1 1 2 2 2 3 4 4 6 6 6 6]

我想根据自己的位置获取每个唯一编号的位置。

y = [1 2 3 4 5 1 2 3 1 1 2 1 2 3 4]

此刻我正在使用:

y = sum(triu(x==x.')) % MATLAB 2016b and above

它很紧凑,但内存效率明显不足。

为使MATLAB编程具有纯粹的美感,我将避免使用循环。您是否有更好的简单实现?

上下文:

我的最终目标是对向量x进行排序,但受到一个约束,即出现次数N的数字优先于出现次数超过N的另一个数字:< / p>

[~,ind] = sort(y);
x_relative_sort = x(ind);
% x_relative_sort = 1   2   3   4   6   1   2   4   6   1   2   6   1   6   1

5 个答案:

答案 0 :(得分:6)

假设x已排序,这是一个使用uniquediffcumsum的向量化替代:

[~, index] = unique(x);
y = ones(size(x));
y(index(2:end)) = y(index(2:end))-diff(index).';
y = cumsum(y);

现在您可以应用最终排序:

>> [~, ind] = sort(y);
>> x_relative_sort = x(ind)

x_relative_sort =

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

答案 1 :(得分:5)

如果您有正整数,则可以使用稀疏矩阵:

[y ,~] = find(sort(sparse(1:numel(x), x, true), 1, 'descend'));

可以直接计算x_relative_sort

[x_relative_sort ,~] = find(sort(sparse(x ,1:numel(x),true), 2, 'descend'));

答案 2 :(得分:4)

仅出于多样性,这是一个基于accumarray的解决方案。它适用于x排序并包含正整数的问题,如下所示:

y = cell2mat(accumarray(x(:), x(:), [], @(t){1:numel(t)}).');

答案 3 :(得分:4)

仅通过与unique(x)进行比较,您可以提高内存效率,因此您没有较大的N*N矩阵,而是N*M,其中N=numel(x), M=numel(unique(x))

我使用了匿名函数语法来避免声明中间矩阵变量,因为该变量两次使用了-可能会得到改善。

f = @(X) sum(cumsum(X,2).*X); y = f(unique(x).'==x);

答案 4 :(得分:4)

这是我不需要排序的解决方案:

CREATE PROCEDURE sp
    @id int,
    @filter varchar(255) = NULL
AS
BEGIN
    IF (NULLIF(@id, 0) IS NOT NULL)
    BEGIN
        WITH cte AS
        (
            --SELECT here...
        )

        IF (NULLIF(@filter, '') IS NULL)
        BEGIN
            SELECT *
            FROM cte;
        END
    END
END

说明:

x = [1 1 1 1 1 2 2 2 3 4 4 6 6 6 6 1 1 1];
y = cell2mat( splitapply(@(v){cumsum(v)},x,cumsum(logical([1 diff(x)]))) ) ./ x;