【问题标题】:How to combine three integers into one unique tag, such that the tag stays integer in C++?如何将三个整数组合成一个唯一的标签,使标签在 C++ 中保持整数?
【发布时间】:2013-05-22 17:04:02
【问题描述】:

我尝试使用 Cantor 和 Szuszik 配对函数,但例如a = 200, b=201 c=202 结果 P(a, b, c) = P(P(a,b),c) 它已经是一个非常大的数字,不适合 int

【问题讨论】:

  • 输入整数有大小限制吗?
  • 您不能将三个整数唯一地放入一个整数中。必须有一些标签重叠。
  • 我相信,这三个数字可以在区间 [0:1000] 上唯一定义,即使它们是 int 的。所以,配对三个 [0:1000] 的数字将是我的问题
  • OK 没问题,那么。写一个答案。
  • Carl Norum,正如我所说,对于小数字,我们已经接受了限制:a = 500,b = 200,c = 600 P(Szuszik) = 62 851 744 106。而 int 的限制是2 147 483 647. P(a, b) = (a >= b ? a * a + a + b : a + b * b)

标签: c++ integer unique


【解决方案1】:

在 [0:1000] 范围内唯一组合三个数字是没有问题的(假设 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 小于 210,所以这些数字总是适合 10 位。

【讨论】:

  • 你的意思是 [0:1023]?
  • OP 要求输入 1 到 1000 之间的数字。请参阅有关问题的 cmets。
【解决方案2】:

如果所有整数的大小相同,则不能将三个整数唯一地放入一个整数中。但是,您可以将三个较小的整数放入一个较大的整数中。为了优雅起见,我将修改您的问题,说您正在尝试将 4 个 16 位整数打包成 1 个 64 位 int (具有特定要求使解决方案更加清晰)。您可以修改解决方案以满足您的需求:

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));  

编辑:这是一个使用按位运算符和位移的更简洁的版本(它假设每个被打包的整数只使用最低有效的 16 位)

uint64_t a = 61000, b=60000, c=48000, d=32000;
uint64_t e = 0;

e = (a << 48) | (b << 32) | (c << 16) | d;

【讨论】:

  • 多么优雅、深思熟虑的答案! @2to1mux Stack Overflow 可以使用更多像你这样的优秀绅士!加油!
【解决方案3】:

如果整数的顺序很重要(所以tag(a,b,c) != tag(b,c,a)),您需要一个大小为N^3 的标签,其中N 是输入整数的最大值。 N^3 - 因为这是您可以制作的(a,b,c) 可能的三倍数。每个都必须映射到唯一的值。所以你需要你的标签能够保持N^3 的值。映射可以为:a + b * N + c * N^2

【讨论】:

    猜你喜欢
    • 2022-11-21
    • 1970-01-01
    • 2020-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-17
    • 1970-01-01
    • 2017-11-14
    相关资源
    最近更新 更多