0

我有以下向量v = [r1 r2 r3 r4 r5 .... rn],带有r整数。

我想检查:

如果r1不等于r2不等于r3... 不等于rn(彼此不同):
打印 v

else(有些元素相等,有些不相等):
打印相等元素的索引。

4

3 回答 3

3

我建议使用unique命令。它将返回所有唯一值的值。

如果要检查矩阵中的所有值v是否唯一,我将使用以下命令:

everything_is_unique = length(unique(v))==length(v);

您还可以返回相等元素的索引。有关更多信息,请参阅文档。unique

于 2013-07-01T20:35:58.187 回答
2

我将再提供一个解决方案,并对迄今为止尝试的所有方法进行比较。

我的解决方案是基于这样的观察,即当使用sort()or之类的内置函数时unique(),您会失去早期逃生的机会。也就是说,sort()必须先对向量进行完全排序,然后才能继续使用算法,即使如果在sort.

因此,我只需遍历数组,并使用 . 将当前值与所有后续值进行比较any()。这可以解决其中一些问题,并且在很多情况下都可以很好地工作。

然而,最坏情况的复杂度是O(N²)sort() ,这比只有O(N·log(N))的 更糟糕。所以像往常一样,这一切都取决于上下文:)

试试这个:

clc

N = 1e4;

% Zigzag's solution
tic
for ii = 1:1e2
    v = randi(N, N,1);
    length(unique(v))==length(v);
end
toc


% Dennis Jaheruddin's solution 
tic
for ii = 1:1e4
    v = randi(N, N,1);
    all(diff(sort(v)));
end
toc

% My solution 
tic
for ii = 1:1e4
    v = randi(N, N,1);
    cond = true;
    for jj = 1:numel(v)
        if any(v(jj) == v(jj+1:end))
            cond = false; 
            break; 
        end
    end
end
toc

随机数在循环内生成,以确保会出现各种不同的情况。我的电脑上的结果:

Elapsed time is 16.787976 seconds.  % unique
Elapsed time is 14.284696 seconds.  % sort + diff
Elapsed time is  5.376655 seconds.  % loop + any

因此,带有提前退出的显式循环(前提feature accel是打开)实际上几乎比标准的“矢量化”方法快三倍:)

PS - 我还尝试嵌套另一个循环以尝试改进在检测相等值之前必须比较所有值(首先v(jj)==v(jj+1:end)完全评估,然后any()才能开始工作),但是在这里,开销真的开始妨碍(或JIT 不能很好地应对这种事情,我不知道)。理论上,这当然应该更快,但不幸的是,不是在 MATLAB 中:)

但是,更改随机数生成

v = randi(N, N,1);

进入

v = randi(N*N, N,1);

结果完全不同:

Elapsed time is 0.162625 seconds.   % unique
Elapsed time is 0.147369 seconds.   % sort + diff
Elapsed time is 30.767247 seconds.  % loop + any

这里我只使用了 100 次迭代而不是 10.000 次,原因很明显:)

于 2013-07-02T10:23:51.897 回答
2

除了使用 unique 之外,您还可以对元素进行排序并检查它们是否都不同:

all(diff(sort(v)))

通过使用带有更多输入参数的排序,您可以获得您正在寻找的索引。

于 2013-07-02T09:35:39.987 回答