2017-01-30 11 views
0

私はバイナリ検索を実装しています。この関数は、配列に見つかったときにターゲット値のインデックスを返します。それ以外の場合は-1です。ダウンキャスト配列の長さとインデックス

usizeではなく、i32のインデックスを扱うことをお勧めします。ターゲットが見つからない場合は、-1を返すためにネガを許可する必要があります。私は関数の端に明示的にキャストしています。これの周りには、より錆びた方法は何ですか?

fn binary_search(nums: &[i32], target: i32) -> i32 { 
    let num_size: i32 = nums.len() as i32;   // This seems bad 
    bsearch(nums, target, 0, num_size as usize) 
} 

fn bsearch(nums: &[i32], target: i32, lo: usize, hi: usize) -> i32 { 
    if hi < lo { 
     return -1; 
    } 

    let mid_idx = lo + ((hi - lo)/2); 
    let guess = nums[mid_idx]; 

    if guess > target { 
     bsearch(nums, target, lo, mid_idx - 1) 
    } else if guess < target { 
     bsearch(nums, target, mid_idx + 1, hi) 
    } else { 
     mid_idx as i32      // This seems bad 
    } 
} 
+1

また、[binary_search'の標準ライブラリ実装](https://doc.rust-lang.org/std/primitive.slice.html#method.binary_search)を見て、ヒントを得ることもできますどのような慣用的な錆の方法であろうか。 – Shepmaster

+0

これは考慮していなかった、ありがとう! –

答えて

7

あなたは不必要に言語と戦っています。 i32は配列インデックスには適切な型ではありません。代わりに、あなたはOptionを使用する必要があります。

fn binary_search(nums: &[i32], target: i32) -> Option<usize> { 
    let num_size = nums.len(); 
    bsearch(nums, target, 0, num_size) 
} 

fn bsearch(nums: &[i32], target: i32, lo: usize, hi: usize) -> Option<usize> { 
    if hi < lo { 
     return None; 
    } 

    let mid_idx = lo + ((hi - lo)/2); 
    let guess = nums[mid_idx]; 

    if guess > target { 
     bsearch(nums, target, lo, mid_idx - 1) 
    } else if guess < target { 
     bsearch(nums, target, mid_idx + 1, hi) 
    } else { 
     Some(mid_idx) 
    } 
} 

指標のためusizeを使用するを持って配列を扱う関数であることを考えると、代わりにi32を使用するように強制するには利点がありません。 i32が見つからないようにするには、-1にする必要がある場合は、関数の終了後に変換を実行できます。


注:また、i32を使用しているとき、あなたは本当に境界チェックを行う必要があることに留意してください。 64ビットシステムでは、配列の長さはi32を大幅に上回り、32ビットマシンでも負の配列インデックスを持つリスクがあります。

+0

私は、 'Option'がセンチネルの値よりもクリーンであることに同意します。しかし、サイズについての注釈は脚注として良いと思います。 "*特に、配列の長さがi32が表現できるものを大幅に超えることができる64ビットシステム*"は理論上ですが、実際には20億個以上の要素を扱う頻度はどれくらいですか? Zero-Sized Typeとは別に、可能な限り最小の要素サイズ(u8)で2億個以上の要素があり、そのサイズはそこから上方に向かっています。ほとんどのソフトウェアプログラムは、そのようなサイズのコレクションを扱う必要はないので、その重視を置くと答えが弱くなる可能性があります。 –

+0

@MatthieuM。私は少し言い直しましたが、それはすでに最後の段落であることを考えると、どのくらいの脚注が得られるのでしょうか。 –

+0

私はそれを撮った、あなたがそれを好きでない場合は元に戻すこと自由に感じる。 –

関連する問題