我修改了答案。非常感谢你扩展了你的答案!我看起来是个不错的解决方案。通宵思考这个问题,我还发现了一种替代方法,它不需要定义类似术语的东西。我不确定是否应该将其作为备选答案发布,或者发布在评论或原始问题中?@Oriol Canela Xandri-如果您的方

我修改了答案。非常感谢你扩展了你的答案!我看起来是个不错的解决方案。通宵思考这个问题,我还发现了一种替代方法,它不需要定义类似术语的东西。我不确定是否应该将其作为备选答案发布,或者发布在评论或原始问题中?@Oriol Canela Xandri-如果您的方,c,mapping,bit-manipulation,bitwise-operators,C,Mapping,Bit Manipulation,Bitwise Operators,我修改了答案。非常感谢你扩展了你的答案!我看起来是个不错的解决方案。通宵思考这个问题,我还发现了一种替代方法,它不需要定义类似术语的东西。我不确定是否应该将其作为备选答案发布,或者发布在评论或原始问题中?@Oriol Canela Xandri-如果您的方法也解决了问题,那么您不应该将其隐藏在评论中(代码格式有限),但是不要犹豫,把它作为一个答案贴出来。非常感谢你的答案,并花时间写下来。这听起来是一个很好的起点。我当然可以使用算术运算,但我担心它们可能更容易污染(正如您已经指出的)相邻位。无论如


我修改了答案。非常感谢你扩展了你的答案!我看起来是个不错的解决方案。通宵思考这个问题,我还发现了一种替代方法,它不需要定义类似术语的东西。我不确定是否应该将其作为备选答案发布,或者发布在评论或原始问题中?@Oriol Canela Xandri-如果您的方法也解决了问题,那么您不应该将其隐藏在评论中(代码格式有限),但是不要犹豫,把它作为一个答案贴出来。非常感谢你的答案,并花时间写下来。这听起来是一个很好的起点。我当然可以使用算术运算,但我担心它们可能更容易污染(正如您已经指出的)相邻位。无论如何,我认为你的回答可以为我指明解决这个问题的正确方向。除非有人给出更好的答案,否则我会将其标记为已被接受的答案。只是更新一下,你的答案启发我找到了一个通用的解决方案。我把它贴在这里作为答案。我会让你知道的,以防你感兴趣。谢谢你的帮助。
0 -> 2
1 -> 1
2 -> 1
  0, 1, 2, 1, 2, 0, ... //Original array of keys
 00 01 10 01 10 00 ...  //2-bit pairs representation of keys in a 32bit int
 10 01 01 01 01 10 ...  //2-bit pairs transformed using the given rule.
#include <stdio.h> 
#include <stdlib.h> 

int main(void) 
{ 
    int i;

    unsigned int keys[16];
    unsigned int bitKeys = 0;

    unsigned int mapping[3];

    unsigned int result[16];
    unsigned int bitResults = 0;

    //Initialize random keys and mapping dict    
    for(i = 0; i<16; i++) 
        keys[i] = rand() % 3;
        bitKeys |= keys[i] << (2*i);

    for(i = 0; i<3; i++) 
        mapping[i] = rand() % 3; 

    //Get results without using bitwise opperations.
    for(i = 0; i<16; i++) 
        result[i] = mapping[ keys[i] ];
        bitResults |= result[i] << (2*i);


    //Would it be possible to get bitResults directly from bitKeys efficiently by using bitwise operations?


    return 0; 
} 
BA QP

00 10
01 01
10 01
11 XX
Q = ¬A·¬B
P = A + B
    uint32_t keys = 2<<30|0<<10|1<<8|2<<6|1<<4|2<<2|0;  // for example
    uint32_t vals = ~keys & ~keys<<1 & 0xAAAAAAAA   // value_high is !key_high & !key_low
                  | (keys>>1 | keys) & 0x55555555;  // value_low is key_high | key_low
0    ¬A·¬B    A    ¬B    B    ¬A    A+B    1
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

int main()
{
    int i;
    unsigned mapping[3];
    // generate example mapping
    for (i = 0; i < 3; ++i) mapping[i] = rand() % 3, printf(" %d->%d", i, mapping[i]);
    puts("");

    // determine the mapping expression index 0..7 for high and low value bit
    short h = mapping[0]/2 | mapping[1]/2<<1 | mapping[2]/2<<2;
    short l = mapping[0]%2 | mapping[1]%2<<1 | mapping[2]%2<<2;

    uint32_t keys = 0x1245689A; // for example

    uint32_t b = keys, a = keys<<1;
    uint32_t term[8] = { 0, ~a&~b, a, ~b, b, ~a, a|b, -1 };  // all possible terms
    uint32_t vals = term[h]    & 0xAAAAAAAA   // value_high
                  | term[l]>>1 & 0x55555555;  // value_low
    printf("%8x\n%8x\n", keys, vals);
}
0 -> 2
1 -> 1
2 -> 1
0 -> 0
1 -> 3
2 -> 3
uint32_t keys = /*...*/;
uint32_t values = (((keys & 0xAAAAAAAAu) >> 1) | ((keys & 0x55555555u) << 1))
        ^ 0xAAAAAAAAu;
uint32_t keys = /*...*/;
uint32_t values = 0xAAAAAAAAu
        - (((keys & 0xAAAAAAAAu) >> 1) | (keys & 0x55555555u));
#include <stdio.h> 
#include <stdlib.h> 

void printBits(size_t const size, void const * const ptr)
{
    unsigned char *b = (unsigned char*) ptr;
    unsigned char byte;
    int i, j;

    for (i=size-1;i>=0;i--)
    {
        for (j=7;j>=0;j--)
        {
            byte = (b[i] >> j) & 1;
            printf("%u", byte);
            if(j%2 == 0) printf("|");
        }
    }
    puts("");
}

int test2BitMapping(unsigned int * mapping)
{
    int i;

    unsigned int keys[16];
    unsigned int bitKeys = 0;

    unsigned int b = 0;
    unsigned int c = 0;
    unsigned int d = 0;
    unsigned int expand[4] = {0x00000000u, 0x55555555u, 0xAAAAAAAAu, 0xFFFFFFFFu};
    unsigned int v12 = 0;
    unsigned int v0mask = 0;

    unsigned int result[16];
    unsigned int bitResults = 0;
    unsigned int bitResultsTest = 0;

    //Create mapping masks
    b = ((1 & mapping[1]) | (2 & mapping[2]));
    c = (2 & mapping[1]) | (1 & mapping[2]);
    d = mapping[0];

    b = expand[b];
    c = expand[c];
    d = expand[d];

    //Initialize random keys
    for(i = 0; i<16; i++) {
        if(0) { //Test random keys
            keys[i] = rand() % 3;
        }
        else { //Check all keys are generated
            keys[i] = i % 3;
        }
        bitKeys |= keys[i] << (2*i);
    }

    //Get results without using bitwise opperations.
    for(i = 0; i<16; i++) {
        result[i] = mapping[ keys[i] ];
        bitResultsTest |= result[i] << (2*i);
    }

    //Get results by using bitwise opperations.
    v12 = ( bitKeys & b ) | ( (~bitKeys) & c );
    v0mask = bitKeys | (((bitKeys & 0xAAAAAAAAu) >> 1) | ((bitKeys & 0x55555555u) << 1));
    bitResults = ( d & (~v0mask) ) | ( v12 & v0mask );


    //Check results
    if(0) {
        for(i = 0; i<3; i++) {
            printf("%d -> %d, ", i, mapping[i]); 
        }
        printf("\n"); 
        printBits(sizeof(unsigned int), &bitKeys);
        printBits(sizeof(unsigned int), &bitResults);
        printBits(sizeof(unsigned int), &bitResultsTest);
        printf("-------\n");
    }
    if(bitResults != bitResultsTest) {
        printf("*********\nDifferent\n*********\n");
    }
    else {
        printf("OK\n");
    }
}

int main(void) 
{ 
    int i, j, k;
    unsigned int mapping[3];

    //Test using random mapping
    for(k = 0; k < 1000; k++) {
        for(i = 0; i<3; i++) {
            mapping[i] = rand() % 3; 
        }
        test2BitMapping(mapping);
    }

    //Test all possible mappings
    for(i = 0; i<3; i++) {
        for(j = 0; j<3; j++) {
            for(k = 0; k<3; k++) {
                mapping[0] = i;
                mapping[1] = j;
                mapping[2] = k; 

                test2BitMapping(mapping);
            }
        }
    }


    return 0; 
}