2017-06-29 4 views
1

ベクトルの前半を反復(読み込み)し、最初の半分に応じて後半の構造を変更する慣用方法は何ですか?これは非常に抽象的ですが、いくつかのアルゴリズムがこの問題に沸騰する可能性があります。私はラストにこの単純化C++の例を書きたい:配列の半分をイディオム的に反復し、もう一方の構造を変更する方法はありますか?

for (var i = 0; i < vec.length; i++) { 
    for (var j = i + 1 ; j < vec.length; j++) { 
     if (f(vec[i], vec[j])) { 
      vec.splice(j, 1); 
      j--; 
     } 
    } 
} 
+0

例と同じことをする慣用的なアプローチを求めていますか?あなたはそれ以外の明確な問題を提示していないようです。ちなみに、私はあなたに無関係のコメントを将来問題から外すことをお勧めします。 –

+0

私は配列の一部を読み込み、同時に配列の他の部分を構造的に変更したいと思います。だから、与えられた瞬間、配列の0..k部分は変更されずに残っているが、k..lenは任意に再構築することができる(例えばランダムな方法で)。私は、現実世界の明確な例を与えることはできません。しかし、私はそのような問題が起こるかもしれないという直感を持っています。だから可能な限り一般的なものにしよう。そして最も重要なことは、借用チェッカーのないこの問題は、C言語のような明確な解決策を持っていることです。 –

+2

問題は、その問題への影響を理解することなしにあまりにも一般的にしてはいけないということです。特に、ベクターに要素を追加したり削除したりできますか?それは問題をはるかに困難にします。特定の問題に絞っておけば、本当に役に立つかもしれません。 –

答えて

4

簡素化を可能に何ら制約はありません、この一般的な問題の慣用的な解決策は、錆やCのために同じになります。

ベクトルの再割り当てによってイテレータに含まれる参照が無効になるため、インデックスを使用する必要があります。長さを変えることができるので、各サイクルでベクトルの現在の長さとインデックスを比較する必要があります。したがって、慣用的な解決策は、次のようになります。このコードは一般的なケースをカバー

let mut i = 0; 
while i < v.len() { 
    let mut j = i + 1; 
    while j < v.len() { 
     if f(v[i], v[j]) { 
      v.splice(j, 1); 
     } else { 
      j += 1; 
     } 
    } 
    i += 1; 
} 

Playground link

ますが、それはまれに有用です。それは、通常は手元の問題に固有の特質を捕捉しません。コンパイラはコンパイル時にエラーをキャッチできません。私は最初に別のアプローチを考えずにこのようなことを書いてはお勧めしません。

+1

これは実際には慣用的ではありません。少なくとも最初の 'while'ループは、ある範囲で' for'ループで置き換えることができます:https://play.rust-lang.org/?gist=081a39fcadd677664f14a939e69f91a3&version=stable&backtrace=0 –

+1

@PeterHall、範囲はこれでいいです問題の特定のインスタンスを生成しますが、外部ループが 'v [i]'にアクセスしないという前提が必要です。 https://play.rust-lang.org/?gist=3e12a336894900d1c819f0e9a2f0866e&version=stable&backtrace=0 – red75prime

関連する問題