O vídeo original é o ensino da estação B de Zuo Chengyun
Diretório de artigos
XOR:
10010
^ 01100
--------
11110
natureza
- 0 ^ N = N,N ^ N = 0
- a ^ b = b ^ a (comutativo)
- a ^ b ^ c = a ^ (b ^ c) (lei da combinação) a mesma pilha de números, não importa como a ordem do cálculo XOR mude, o XOR deve ter o mesmo resultado
1 valor de troca XOR
Troca os valores de duas variáveis (sem introduzir espaço temporário adicional). Observe que a e b podem ser variáveis diferentes, mas não a mesma variável.
a = a ^ b //第一行:a = a ^ b; b = b
b = a ^ b //第二行:a = a ^ b; b = b ^ a ^ b = a (因为b ^ b = 0, 0 ^ a = a)
a = a ^ b //第三行:a = a ^ b ^ a = b b = a
2 Encontre o único número que aparece um número ímpar de vezes na matriz
Requer complexidade de tempo O(n) complexidade de espaço O(1)
void printOddTimesNum(const std::vector<int>& arr)
{
int eor = 0;
for (int cur : arr){
eor ^= cur;
}
cout << eor << endl;
}
// eor = 1 ^ 1 ^ 2 ^ 2 ^ 3 ^ 3 ^ .... ^ odd ^ 24 ^ 24 ^.....
// 最后 eor 会等于那个出现奇数次的,出现偶数次的数都被自己消除掉了
3 Encontre os dois números que aparecem um número ímpar de vezes na matriz
A matriz tem dois números que aparecem em tempos ímpares e os outros números são pares
(requer complexidade de tempo O(n) complexidade de espaço O(1) )
- Ainda temos um número ímpar de vezes para obter eor (nome completo OR exclusivo) primeiro, mas no final eor será igual a a ^ b, porque os tempos pares se tornam 0
- Como esses dois números são diferentes , se você os converter para binário, pelo menos um bit será diferente (um 0, um 1). O resultado do cálculo XOR de eor neste bit deve ser 0 ^ 1 = 1. Pelo menos um: Engenhoso, embora possa haver muitos bits que são 1, só precisamos retirar um deles. Aqui, por conveniência, pegue diretamente o mais à direita em eor que é 1 (use eor & (~eor + 1 ) ) .
- Tirar o 1 mais à direita de eor é usado para dividir os elementos da matriz em dois grupos (o número cujo bit é 0 e o número cujo bit é 1). Porque eor = a ^ b, e o bit de eor é 1, então ab deve ser diferente neste bit, então ab deve estar localizado nos dois números respectivamente (o objetivo principal é separá-los)
- Em seguida, vem a operação de chave: use o novo eor' para XOR todos os elementos da matriz cujo bit é 1. Este passo é o mesmo da questão 1.2, o resultado deve ser a ou b, assumimos eor' = a . Finalmente, use eor' ^ eor para obter outro número ímpar, ou seja, eor = eor' ^ eor = a ^ a ^ b = b .
#include <iostream>
#include <vector>
void printOddTimesNum2(const std::vector<int>& arr)
{
int eor = 0;
for (const int& cur : arr){
eor ^= cur;
}
// 目前 eor = a ^ b , eor != 0 且必然至少有一个位是1
int rightOne = eor & (~eor + 1);
int eor1 = 0;
for (const int& cur : arr){
if ((rightOne & cur) == rightOne){
// 与该位为1的组所有元素进行异或
eor1 ^= cur;
}
}
// eor1 得到的是a 或 b 不确定
cout << eor1 << ' ' << eor1 ^ eor << endl;
}
A função de eor & (~eor + 1) no código é obter o último 1 da string binária de destino e todos os 0s depois dele.
Supondo que eor seja 1010111100,
podemos usareor & (~eor + 1)
esse binário mais à direita que pode extrair esse número ( eor) 1 e valores subseqüentes, ou seja, 100