2009-04-20 10 views
2

私はマージソート機能を研究しています。ソートをダウンしました - 私はマージパートを完成させようとしています。私はC++を学んでいると仮定し、ポインタの大雑把な知識を持っていて、std :: vector :: iterator(またはstd :: vectorのこと)のルールをすべて理解していないとします。C++で(for each in)ループを埋め込むことができます

numは、サイズが "int ar [num]"の配列からコピーした(std :: copy)値を持つ元のstd :: vectorのサイズであるとします。 farrayは(0から(num/2))の値を持ち、sarrayは((num/2)からnumまで)の値を持つとします。

このコードはコンパイルされ、Bloodshed Dev-C++の最新の安定版ビルドでは警告やエラーは発生しません。私はこれが有効かどうかわからない、私はまだ最後のすべての値を試して試してみる必要があります。私はこれが一般的なものか、エラーの起こりやすいものか、あるいは悪いものかを知りたいだけです。もしそうなら、どうすればいいのですか?

+0

イテレータなどを把握しようとしている場合は、よく知られている表記法([]演算子など)を使用して記述してから、イテレータにスワップすると便利です。しかし、反復子は理解するのが大切なので、特にマップやセットなどの他の型になるときは、[]を使用しないでください。 – Smashery

答えて

7

これは有効ですが、forループはおそらくあなたが望むものではありません。 2つのforループを使用すると、内側のループは、外側のループがループするたびに最初に戻ります。あなたはすべての単一の組み合わせをテストし、最終リストに1より大きいを追加しているので、

10 10 10 10 10 9 9 9 9 9 8 8 8 8 8 7 6 4 4 4 7 6 4 3 3 

:だからあなたのベクトルが含まれている場合:

farray: 10 9 8 4 3 
sarray: 7 6 4 3 1 

そして、最終的な配列のようなものが含まれます。より良い解決法は、各リストのイテレータを覚えて、ただ一つのループを使うことです。リストをループするのではなく、両方とも一緒に行く - もしsarrayが大きいならば、あなたのsarrayイテレータを増やして、それを古いfarrayイテレータと比較する。 sarrayとfarrayの両方が空の場合、ループを止めてください。

vector<int> fiter = farray.begin(); 
vector<int> siter = sarray.begin(); 
vector<int> final; 

// Let's traverse both farray and sarray. 
// We'll want to stop this loop once we've traversed both lists. 
while (fiter != farray.end() && siter != sarray.end()) 
{ 
    if (fiter == farray.end()) 
    { 
     // we must have gone right through farray - 
     // so use the value from sarray, and go to the next one 
     final.push_back(*siter); 
     siter++; 
    } 
    else if (siter == sarray.end()) 
    { 
     // we must have gone right through sarray - 
     // so use the value from farray, and go to the next one 
     final.push_back(*fiter); 
     fiter++; 
    } 
    else if (*siter > *fiter) 
    { 
     // siter is the bigger of the two - add it to the final list, and 
     // go to the next sarray entry 
     final.push_back(*siter); 
     siter++; 
    } 
    else // *fiter >= *siter 
    { 
     // fiter is the bigger of the two - add it to the final list, and 
     // go to the next farray entry 
     final.push_back(*fiter); 
     fiter++; 
    } 
} 

私はそれをテストしていない - これは宿題のためであれば、その後、試みは、私がやったかを理解するためにしてください離れて行くと、それを自分で書くのではなく、コピー+ペースト。

+0

実装について説明しますか? – jkeys

+0

私は、(テストされていない)実装の例を挙げました。ループ中に1つしか使用せず、両方のリストを通過するまで処理を続けます。それが1つのリストを通して完全に作成されている場合、それはuntraversedリストにそれらを追加するだけです。それ以外の場合は、2つの項目を比較し、そのリスト内のイテレータをインクリメントする前に、大きな項目を追加します。 – Smashery

+0

さらに、 'final'は 'num'エントリが0で始まるように作成されています。その後、実際のエントリが追加されます。私はそれが望ましい行動だとは思わない。 –

1

ループ変数を再利用しない限り、どんな種類のループ(while、do、while)もネストすることができます。あなたが試みるなら、それはコンパイルされますが、実行時に悲惨に失敗するかもしれません。最近のCやC++では、ネストされたループ変数に同じ名前を使用することは技術的に許可されていますが、混乱し、避けるべきです。

ループ変数の再利用に関する前述の問題を除いて、単一ループよりもエラーが発生しにくくなりました。

ネストループのlimitsについて詳しくは、こちらをご覧ください。

+0

ネストされたループでループ変数を再利用することができます。通常は良いアイデアではありませんが、実行時にあなたが自分のやることに慎重であれば、自動的にクラッシュすることはありません。 – Peter

+0

int i = 0を使用して両方のループを反復処理するような意味ですか?あなたは組み込みループか外部ループでそれを増やしますか? – jkeys

+0

実行時に障害が発生しても必ずしもクラッシュするわけではありません。単に間違った結果を計算することができます。 – lothar

0

はい、これを行うことができます。そして、はい、それはしばしばエラーになりがちです。実際には、ループを書くこと自体がエラーになりがちです。これはfor_each、copy、transformのようなSTLのアルゴリズムを使用する1つの引数です。二つの変数IJとループのネストされたよう

+0

ハハ、私はそれほど先ではありません。実際には、このプログラムでstd :: copyを使用して、元の配列[num]からstd :: vectororiginalに値をコピーしています。 – jkeys

+0

私は本当に時々これらの馬鹿が誰になったのだろうかこのような投票の回答があります。 –

+0

フック:for_each()は、for_each(v.begin()、v.end()、doSomething())のように、範囲内の各要素に対して同じ操作を実行するために使用されます。 'doSomething()'はいわゆるファンクタで、 'v'の各値に対して実行されます。 –

2

マージソートアルゴリズムはさておき、イテレータのでループのためにネストされて同じように有効です。

+0

イテレータは私の唯一の選択だと私は理解していました。整数を使用してstd :: vector vを反復処理できますか? – jkeys

+0

もちろん可能です。配列やat()メンバ関数と同様に、[]演算子を使用します。詳細については、お気に入りのSTLのドキュメントを参照してください。 –

+0

この場合イテレータはポインタまでコンパイルされ、inder []を使うだけで同じように動作しますが、一般的にネストされたループの性質を指しています。 –

0

はい、ループ(または他の文)を入れ子にすることができます(理由の範囲内で、別の答えに記載されているように制限がありますが、必要なもの以上に制限があります)。

1

ループのネストは、物事を行うための全く正当な方法です。たとえば、2D配列をトラバースするのは古典的な「古い学校」の方法です.1つのループがy軸に、もう1つのループがx軸に移動します。これらの子供たちと今日で

、およびその各ループやイテレータとマッピング機能のために間違いなく「より良い」が、ネスティングループ(いくつかの定義を良い方向に)、それを行うための方法だけで正常に動作があります。 C++やポインタを使ってもそれは変わりません。

関連する問題