从集合中随机给定整数 0、1 和 2 时获取整数 0、1 和 2 的快速方法

fast way to get integers 0, 1, and 2 when given a random one from the set

本文关键字:整数 获取 方法 集合 随机      更新时间:2023-10-16

所以基本上

int num = rand(2); //random number from 0-2
int otherNum, otherOtherNum;
otherNum = implement this
otherOtherNum = implement this

例如,如果 num 为 2,则 otherNum 和 otherOtherNum 必须设置为 0 和 1(或 1 和 0)。

您将如何实现这一点?假设您不能使用分支表或查找表。是的,我想要一个操纵解决方案。是的,我希望该解决方案比使用模运算符的解决方案更快(因为这本质上是一个除法)。

我认为查找可能是最快的,但不确定,但我不喜欢这种解决方案。

您也可以使用 XOR 和位掩码来执行此操作。

#include <stdio.h>
void
f(unsigned val, unsigned ary[3])
{
    ary[0] = val;
    ary[1] = (ary[0] ^ 1) & 1;
    ary[2] = (ary[0] ^ 2) & 2;
}
int
main()
{
    unsigned ary[3] = {0};
    f(0, ary);
    printf("f(0) = %d %d %dn", ary[0], ary[1], ary[2]);
    f(1, ary);
    printf("f(1) = %d %d %dn", ary[0], ary[1], ary[2]);
    f(2, ary);
    printf("f(2) = %d %d %dn", ary[0], ary[1], ary[2]);
    return 0;
}

这将打印:

f(0) = 0 1 2
f(1) = 1 0 2
f(2) = 2 1 0
otherNum = (num + 1) % 3
otherOtherNum = (num + 2) % 3

如果对查找表的限制意味着避免内存访问,则可以使用寄存器内查找表。寄存器内查找表只是一个编译时常量。

const int tab = ((1 <<  0) | (2 <<  4) | 
                 (0 <<  8) | (2 << 12) | 
                 (0 << 16) | (1 << 20));
int num = rand(2); //random number from 0-2
int otherNum, otherOtherNum;
otherNum = (tab >> num*8) & 0xf;
otherOtherNum = (tab >> (num*8+4)) & 0xf;

我的 2 次小便。

int main()
{
    std::srand(std::time(0));
    int num = std::rand() % 3; //random number from 0-2
    int otherNum = (0b001001 >> (num << 1)) & 0b11;
    int otherOtherNum = (0b010010 >> (num << 1)) & 0b11;
    std::cout << num << 'n';
    std::cout << otherNum << 'n';
    std::cout << otherOtherNum << 'n';
}

笔记:

0b001001 = 9
0b010010 = 18
0b11 = 3

此方法基本上使用存储在整数位中的表,并将相关位移动到所需的变量中。

另一种选择是使用数组进行查找,这避免了任何加法和模数,尽管我不相信它更快:

int lookup[3] = {1, 2, 0};    
int num = rand(2); //random number from 0-2
int otherNum, otherOtherNum;
otherNum = lookup[num];
otherOtherNum = lookup[otherNum]