8

デモの問題: 2 つstd::bitset<N>の が与えられ、aとの両方にbビットが設定されているかどうかを確認します。ab

この問題には、かなり明白な解決策が 2 つあります。これは、新しい一時的なビットセットを作成し、値をあらゆる場所にコピーして破棄するため、悪いことです。

template <size_t N>
bool any_both_new_temp(const std::bitset<N>& a, const std::bitset<N>& b)
{
    return (a & b).any();
}

この解決策は、一度に 1 ビットずつ進むため、理想的とは言えません。

template <size_t N>
bool any_both_bit_by_bit(const std::bitset<N>& a, const std::bitset<N>& b)
{
    for (size_t i = 0; i < N; ++i)
        if (a[i] && b[i])
            return true;
    return false;
}

block_type理想的には、次のようなことができるようになるでしょuint32_tbitset

template <size_t N>
bool any_both_by_block(const std::bitset<N>& a, const std::bitset<N>& b)
{
    typedef std::bitset<N>::block_type block_type;
    for (size_t i = 0; i < a.block_count(); ++i)
        if (a.get_block(i) & b.get_block(i))
            return true;
    return false;
}

これを行う簡単な方法はありますか?

4

2 に答える 2

6

最初の例を最適化してコンパイルしg++たところ、3 番目のソリューションと同じコードが生成されました。実際、小さいビットセット (320 ビット) を使用すると、完全に展開されました。aとの内容bが不明であることを確認する関数を呼び出さずにmain、実際に全体を最適化しました (両方がすべて 0 であることを知っています)。

教訓: 明白で読みやすいコードを書き、コンパイラーに処理させます。

于 2011-12-02T00:43:14.577 に答える
0

あなたの最初のアプローチは、「値をあらゆる場所にコピーして、それらを破棄する」とおっしゃっています。しかし、実際には余分な値のコピーが 1 つだけあり ( の結果operator&が に返されるany_both_new_temp場合)、値の代わりに参照を使用することで削除できます。

template <size_t N>
bool any_both_new_temp(const std::bitset<N>& a, const std::bitset<N>& b)
{
    std::bitset<N> tmp = a;
    tmp &= b;
    return tmp.any();
}

(しかし、明らかに一時的なものを作成し、そこbitsetにコピーaします。)

于 2011-12-02T00:42:02.523 に答える