3

main() によって渡された配列を並べ替え、重複を削除し、一意の要素の数を返す次の関数に出くわしました。頭を包むのに苦労している最後のビットです。

int reduce(long ar[], int n) {
  sort(ar, ar + n);
  return unique(ar, ar + n) - ar; // ??? 
}

私の理解では、unique() は、配列に一意の値を格納するセグメントの末尾へのポインターを返します。しかし、反復子から配列名を減算すると、一意の要素の数に等しい int が得られる理由、またはunique(ar, ar+n)同じ結果を得るために int に型キャストできない理由がわかりません。

4

2 に答える 2

5

unique(ar, ar+n) を int に型キャストして同じ結果を得ることができない理由。

あなたが言ったようにunique、ポインタを返すからです。ポインタはインデックスではなくメモリ アドレスです。したがって、ポインターを int にキャストしても意味がありません。

イテレータから配列名を減算すると、一意の要素の数に等しい int になる理由

2 つのポインターを (同じ配列に) 減算すると、それらの間の要素の数に評価されます。*


* 以下のコメントで @Nawaz が指摘したように、この結果は署名されています。だから(p1 - p2) == -(p2 - p1)

于 2013-01-05T12:36:09.900 に答える
5

次のような配列があるとします。

{1, 2, 2, 3, 4, 4, 5}

を呼び出した後はstd::unique、おそらく次のようになります (ありがとう、Nawaz)。新しい末尾の後の要素は呼び出し前と同じままです。

{1, 2, 3, 4, 5, 4, 5}
               ^

std::unique配列の新しい末尾、つまり矢印の場所にイテレータを返します。そこから、配列の先頭を減算すると一意の要素の数が返されることは論理的に理にかなっています。もう少し明示的にしたい場合はreturn std::distance(ar, std::unique(ar, ar + n));、 を使用できます。これは、反復子が減算をサポートしていない場合にも機能します。

于 2013-01-05T12:39:44.323 に答える