Operação de bits | (bit a bit ou) & (bit a bit e) ^ (bit a bit exclusivo ou)

Índice

Catálogo de artigos: Este capítulo explica principalmente a série de questões de escovação

        1: Primeiro, as funções e propriedades dos três operadores I & ^ serão introduzidas

        2: Três questões clássicas de teste escrito usando operadores bit a bit (da oferta Jianzhi)

                        O link do tópico é o seguinte:

               1: 136. Números que aparecem apenas uma vez - LeetCode

               2: A espada refere-se à oferta 15. O número de 1s em binário - LeetCode

               3: A espada refere-se à oferta 56 - I. O número de vezes que o número aparece na matriz - LeetCode


O artigo começa oficialmente~~~

          1: operador de bit ^ (exclusivo bit a bit ou) & (bit a bit e) | (bit a bit ou)

        Primeiro de tudo, temos que entender o significado deste bit no operador de bits : este bit é na verdade o que normalmente chamamos de bit binário, portanto, os operadores de bits são usados ​​para realizar operações em bits binários (contendo apenas 0 e 1).

       & : O nome deste operador é bit a bit e, não o confunda com o operador && (ou lógico), a função do & é definir os bits binários de ambos os operandos como 1, e os demais bits são 1. Se houver for 0 ou 1, será transformado em 0. (O entendimento simples é: apenas 1 é 1, caso contrário o valor deste bit é 0).

        Por exemplo: 3 e 5

3&5

假设在32位平台下
3的二进制位:00000000 00000000 00000000 00000011

5的二进制位:00000000 00000000 00000000 00000101

3&5         00000000 00000000 00000000 00000001

全1才为1,其它都为0     

       

        |(OR bit a bit) : Este operador tem o mesmo efeito que o operador acima, exceto que sua função é o oposto de &. Somente todos os 0s no bit binário são 0 e 1 é 1.

        O resultado de 3|5 é o seguinte:

        

3|5
假设在32位平台下
3的二进制位:00000000 00000000 00000000 00000011

5的二进制位: 00000000 00000000 00000000 00000101
3|5的结果    00000000  00000000 00000000 00000111

   ^XOR bit a bit: o mesmo bit binário é 0 e o diferente é 1. Ao mesmo tempo, o operador ^ tem as características da lei comutativa e da lei associativa, por exemplo: a^a=0 porque os bits binários são todos o mesmo    a^0 =a ; 0 não mudará seu bit original    a^ b^a=b, aqui ele reflete sua natureza, que é equivalente a a^a^ b .

       Os pontos de conhecimento estão pavimentados, vamos entrar na explicação dos exercícios.

   2: Perguntas clássicas do teste escrito (operações de bits)

        A dificuldade das questões varia de fácil a difícil!

        1:   136. Números que aparecem apenas uma vez - LeetCode

        

        Esta questão também pode ser chamada de problema do cão único (cachorro)

        Em primeiro lugar, o significado deste tópico é: dê-nos um array, e então há um número no array que aparece apenas uma vez, e os outros números aparecem duas vezes.

Aqui podemos pensar na natureza do operador ^         do qual falamos acima : a^a=0; 0^a=a;

        Como há números na matriz que aparecem duas vezes , podemos eliminar os dois números idênticos após usar ^ , e o número restante na matriz final é o único número que aparece uma vez

        código:

int singleNumber(int* nums, int numsSize){
    int ret =0;
    int i =0;
    for(i=0;i<numsSize;i++)
    {
        ret^=nums[i];
    }
    return ret;
}

        Esta questão usa o operador ^ de forma muito inteligente. Claro, pode haver outros algoritmos para esta questão, como classificação e contagem, tabelas hash... todos podem ser usados ​​para implementar este algoritmo. Mas como estamos falando de operadores bit a bit, usamos operadores bit a bit.

2: Espada refere-se à Oferta 15. O número de 1s em binário

        Usarei duas soluções para esta questão para explicar esta questão:

        Método 1: operador shift mais & operador + contagem

        Ideia: Suponha que conhecemos um número porque apenas o bit 1 mais à direita é 1 e os outros bits são 0, então realizamos uma operação com 1 para cada 1 bit do bit binário do número a ser calculado.

        código:

int hammingWeight(uint32_t n) {
    int count=0;
    int i =0;
    for(i=0;i<32;i++)
    {
        if(((n>>i)&1)==1)
            count++;
    }
    return count;
}

        Método 2: Elimine o 1 do último dígito do número que precisamos e continue o ciclo.

        Ideia: n=n&(n-1);

        Vamos dar um exemplo para explicar:

                Código:

        

int hammingWeight(uint32_t n) {
    int count=0;
    while(n)
    {
        count++;
        n=n&(n-1);
    }
    return count;
}

       3: A espada refere-se à oferta 56 - I. O número de vezes que o número aparece na matriz - LeetCode

        

        Em comparação com as duas questões anteriores, esta questão tem um certo grau de dificuldade e não é tão direta quanto as duas questões acima:

        Vamos explicar através do Liezi real

                A ideia que usamos aqui é grupo XOR

       Então, o que é o grupo XOR?

        Por exemplo, podemos colocar 1 1 3 3 5 em um array e 2 2 4 4 6 em outro array, para que possamos obter 5 e 6 fazendo XOR em cada array.

        Então, como fazemos o agrupamento?

        Primeiro de tudo, fazemos um XOR em todos os números da matriz para obter 5 ^ 6 e, como os dois números não podem ser iguais, o XOR definitivamente não é 1, então um dos dígitos binários no resultado deve ser 1, então iremos Você pode usar este 1 para agrupar.

        Por exemplo, 5 ^ 6

        

        Como 5 e 6 são diferentes neste bit, colocamos o número que é igual a 5 neste bit em um grupo e colocamos o número que é diferente de 5 em outra matriz e, em seguida, XOR-los respectivamente para obter a resposta é acima.

Então, como descobrir qual bit é diferente entre 5 e 6?

        Primeiro, fazemos um XOR de todo o array para obter o valor ^ de 5 e 6 e, em seguida , executamos uma operação & em cada bit desse valor com 1. Se o resultado de encontrar 1 bit & for 1, então podemos marcar esta posição , e então deixe cada valor em nossa matriz original mover o bit pos. Se for & igual a 1, usamos dog1 para ^ subir, se não for igual a 1, então usamos dog2 para ^ subir

        Então no final nosso dog1 é um dos valores e dog2 é o segundo valor.

        código:

int* singleNumbers(int* nums, int numsSize, int* returnSize){
    int*ret=(int*)malloc(sizeof(int)*2);
    int i =0;
    int pos=0;
    int a=0;
    for(i=0;i<numsSize;i++)
    {
        a^=nums[i];
    }
    //a现在为两个数字的异或值 a^b!=0
  
    //标记那个位置为1
    for(i=0;i<32;i++)
    {
        if(a>>i&1==1)
        {
            pos=i;
            break;
        }
    }
    int dog1=0;
    int dog2=0;
    //根据pos位置分为两个数组,直接异或就是我们所需要的答案了
    for(i=0;i<numsSize;i++)
    {
        if((nums[i]>>pos)&1==1)
        {
            dog1^=nums[i];
        }
        else
        {
            dog2^=nums[i];
        }
    }
    ret[0]=dog1,ret[1]=dog2;
    * returnSize=2;
    return ret;
}

        Os exemplos clássicos neste capítulo são explicados, obrigado por assistir~~

                Se você acha que é útil para você, pode gostar! !

        

Acho que você gosta

Origin blog.csdn.net/2201_75964502/article/details/132714292
Recomendado
Clasificación