3

uint64_t (C++11 から) で表される (バイナリ) 行列を取得しました。また、任意の列から最初のランクに効率的にマップできるようにしたいと考えています。例えば

0 1 0 0 0 0 0 0
0 1 0 0 0 0 0 0
0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0
0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0

uint64_t matrice = 0x4040400040400040uLL;
uint64_t matrice_2 = map(matrice, ColumnEnum::Column2);

1 1 1 0 1 1 0 1
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0

matrice_2 には 0xED00000000000000uLL が含まれます。

4

3 に答える 3

3

ちょっといいなぞなぞ。かなり読みやすいバージョンを次に示します。

matrice = (matrice >> (8ull - column)) & 0x0101010101010101ull;
uint64_t result((  ((matrice >>  0ul)  & 0x01ull)
                 | ((matrice >>  7ul)  & 0x02ull)
                 | ((matrice >> 14ull) & 0x04ull)
                 | ((matrice >> 21ull) & 0x08ull)
                 | ((matrice >> 28ull) & 0x10ull)
                 | ((matrice >> 35ull) & 0x20ull)
                 | ((matrice >> 42ull) & 0x40ull)
                 | ((matrice >> 49ull) & 0x80ull)) << 56ull);
于 2012-11-16T22:51:11.817 に答える
3

素晴らしい質問です。ハッキングは本当に楽しかったです。これが私の解決策です:

uint64_t map(uint64_t x, int column)
{
  x = (x >> (7 - column)) & 0x0101010101010101uLL;
  x = (x | (x >> 7)) & 0x00FF00FF00FF00FFuLL;
  x = (x | (x >> 14))& 0x000000FF000000FFuLL;
  x = (x | (x >> 28))& 0x00000000000000FFuLL;
  return x << 56;
}

実際の例はideoneにありますmap(matrice, ColumnEnum::Column2)

于 2012-11-16T23:23:35.940 に答える
1

最初にすべての列のビットマスクを定義します。

uint64_t columns[8] = {
  0x8080808080808080uLL,
  0x4040404040404040uLL,
  //...
  0x0101010101010101uLL
};

列ビットマスクを「行列」に適用すると、次の列のみが得られます。

uint64_t col1 = matrice & columns[1]; // second column - rest is empty

シフトすると、最初の列のケースのみを取得できます。

uint64_t col0 = (col1 << 1); // second column - rest is empty
//                       ^ this number is just zero based index of column,,,

これで、最初のビットが正しい場所に配置されました。次の 7 ビットを設定するだけです。

 col0 |= (col0 & (1 << 55)) << 7; // second bit...
 // ....

または、単に使用std::bitset<64>します....

于 2012-11-16T22:43:03.940 に答える