0

次の vectorv = [r1 r2 r3 r4 r5 .... rn]があり、r整数が含まれています。

確認したい:

if r1not equal to r2not equal to r3... not equal to rn(互いにすべて異なる):
print v

else (いくつかの要素は等しく、他の要素は等しくない):
等しい要素のインデックスを出力します。

4

3 に答える 3

3

コマンドの使用をお勧めしuniqueます。すべての一意の値の値を返します。

マトリックス内のすべての値vが一意であることを確認したい場合は、次のコマンドを使用します。

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

等しい要素のインデックスを返すこともできます。詳細については、ドキュメントをunique参照してください。

于 2013-07-01T20:35:58.187 に答える
2

もう 1 つの解決策と、これまでに試したすべての方法の比較を示します。

sort()私の解決策は、またはunique()のような組み込み関数を使用すると、早期エスケープの機会を失うという観察に基づいています。つまり、アルゴリズムを続行する前にsort()、ベクトルを完全に並べ替える必要がありますが、2 つの等しい値が 内で既に検出されている場合は必要ありませんsort

したがって、単純に配列を反復処理し、現在の値を を使用して後続のすべての値と比較しますany()。これはこれらの問題のいくつかを回避し、多くの場合に十分に機能します。

ただし、最悪の場合の複雑さはO(N²)であり、 O(N·log(N))sort()しかないよりもはるかに悪いです。いつものように、それはすべて文脈に依存します:)

これを試す:

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

乱数はループ内で生成され、さまざまなケースが確実に発生するようにします。PC での結果:

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オンになっている場合) は、実際には標準の「ベクトル化」アプローチよりもほぼ 3 倍高速です :)

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

ここでは、明らかな理由から、10,000 回ではなく 100 回の反復のみを使用しました :)

于 2013-07-02T10:23:51.897 に答える