2017-04-07 12 views
1

クイックソート用のスワップ機能。それは間違った出力を与えます。私は一時変数を使用すると、正しい出力が得られます。ここ はテスターです:クイックソートのスワップ機能が間違った出力を返す

void swap(int &a,int &b){ 
    a=a+b; 
    b=a-b; 
    a=a-b; 
} 

とはいえ、これは正常に動作します:

void swap(int &a,int &b){ 
    int temp=a; 
    a=b; 
    b=a; 
} 

私はクイックソートアルゴリズムのパーティション関数内で、この関数に配列の要素を渡しています。

+5

「一時変数」と言うと、そのことを詳しく説明できますか?参照は一時変数にバインドできないためです。これは*未定義の動作につながります*あなたが見るような行動につながる可能性があります。 [最小限の、完全で検証可能な例](http://stackoverflow.com/help/mcve)を作成してください。そして、[良い質問をする方法を読む](http://stackoverflow.com/help/how-to-ask)に時間を割けてください。 –

+0

文脈を提供してください。あなたは正しい結果を得るために何を渡しますか? –

+2

あなたのタイプのスワップには、未定義の動作であるアンダーフローまたはオーバーフローがあります。スワップ関数が必要な場合は 'std :: swap'を使い、ライブラリの実装者は自分が何をしているかを知っていると信じてください。 – NathanOliver

答えて

7

3番目の変数のないスワップ用のコードはOKです。残念ながら、このアルゴリズムは、例えば、自分自身との値を交換するために適用することはできません。

void swap(int &a,int &b){ // &a == &b, the value is 123 
    a=a+b;     // a == b == 246 
    b=a-b;     // a == b == 0 (Oops!) 
    a=a-b;     // a == b == 0 
} 

また、(std::swap)を交換するための標準的な機能がありますので注意してくださいとあなたのコードは、最適化なしでコンパイルされた場合、遅く動作しますより多くのメモリ操作を実行するので、通常のスワップ(3番目の変数を使用)よりも優先されます。また、このコードは、整数オーバーフローまたはアンダーフローにつながる可能性があります。これは、標準では定義されていない動作であり、期待どおりに機能しない場合もあります。このリストに可読性の問題(最も重要なもの)を追加すると、推奨はです.3番目の変数を使わないでスワップを使用しないでください。

+1

残念なことにGCCもClangもこれを通常のスワップと同じものに最適化していないので、単に悪化しているだけです。たぶん彼らはいつかやってくれるでしょう。 – harold

+0

@harold訂正していただきありがとうございます。回答テキストに修正されます – alexeykuzmin0

+0

ありがとうございます!!!それは本当に役に立ちました –