Cantor と Szuszik のペアリング関数を使用しようとしましたが、たとえば a = 200, b=201 c=202 結果の P(a, b, c) = P(P(a,b),c) はすでに非常に大きいですintに収まらない数値。
3 に答える
[0:1000] の範囲で 3 つの数値を一意に組み合わせることは問題ありません (int
つまり、システムで 32 ビット以上であると仮定します)。
int combine(int a, int b, int c)
{
return (a << 20) | (b << 10) | c;
}
後で抽出するには:
void unpack(int combined, int *a, int *b, int *c)
{
*a = combined >> 20;
*b = (combined >> 10) & 0x3ff;
*c = combined & 0x3ff;
}
1000 は 2 10より小さいため、このパッキングは安全です。したがって、これらの数値は常に 10 ビットに収まります。
すべての整数が同じサイズである場合、3 つの整数を 1 つの整数に一意に適合させることはできません。ただし、3 つの小さい整数を 1 つの大きい整数に合わせることができます。簡潔にするために、4 つの 16 ビット整数を 1 つの 64 ビット整数にパックしようとしていると言うように問題を修正します (特定の要件があると解決策がより明確になります)。ニーズに合わせてソリューションを変更できます。
uint16_t a = 61000, b=60000, c=48000, d=32000;
uint64_t e = 0;
memcpy((char*)&e, &a, sizeof(a));
memcpy((char*)&e + (1*sizeof(b)), &b, sizeof(b));
memcpy((char*)&e + (2*sizeof(c)), &c, sizeof(c));
memcpy((char*)&e + (3*sizeof(d)), &d, sizeof(d));
編集: これは、ビットごとの演算子とビット シフトを使用したよりクリーンなバージョンです (パックされる各 int は最下位の 16 ビットのみを使用すると想定しています)。
uint64_t a = 61000, b=60000, c=48000, d=32000;
uint64_t e = 0;
e = (a << 48) | (b << 32) | (c << 16) | d;
整数の順序が重要な場合 (そう) 、 が入力整数の最大値であるサイズtag(a,b,c) != tag(b,c,a)
のタグが必要です。- これは、作成できるトリプルの数だからです。それぞれが一意の値にマップする必要があります。したがって、タグが の値を保持できるようにする必要があります。マッピングは次のように実行できます。N^3
N
N^3
(a,b,c)
N^3
a + b * N + c * N^2