El video original es la enseñanza de la estación B de Zuo Chengyun.
Directorio de artículos
XOR:
10010
^ 01100
--------
11110
naturaleza
- 0 ^ norte = norte, norte ^ norte = 0
- a ^ b = b ^ a (conmutativo)
- a ^ b ^ c = a ^ (b ^ c) (ley de combinación) la misma pila de números, no importa cómo cambie el orden de cálculo de XOR, el XOR debe tener el mismo resultado
1 valor de intercambio XOR
Intercambia los valores de dos variables (sin introducir espacio temporal adicional). Tenga en cuenta que a y b pueden ser variables diferentes pero no la misma variable.
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 Encuentra el único número que aparece un número impar de veces en la matriz
Requiere complejidad temporal O(n) complejidad espacial 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 Encuentra los dos números que aparecen un número impar de veces en la matriz
La matriz tiene dos números que aparecen en tiempos impares, y los otros números son pares
(requiere complejidad de tiempo O(n) complejidad de espacio O(1) )
- Todavía tenemos un número impar de veces para obtener primero eor (nombre completo exclusivo OR), pero al final eor será igual a a ^ b, porque las veces pares se convierten en 0
- Debido a que estos dos números son diferentes , si los convierte a binario, al menos un bit será diferente (un 0, un 1). El resultado del cálculo XOR de eor en este bit debe ser 0 ^ 1 = 1. Al menos uno: Ingenioso, aunque puede haber muchos bits que son 1, solo necesitamos sacar uno de ellos. Aquí, por conveniencia, tome directamente el más a la derecha en eor que es 1 (use eor & (~eor + 1 ) ) .
- Sacar el 1 más a la derecha de eor se usa para dividir los elementos de la matriz en dos grupos (el número cuyo bit es 0 y el número cuyo bit es 1). Debido a que eor = a ^ b, y el bit de eor es 1, entonces ab debe ser diferente en este bit, entonces ab debe ubicarse en los dos números respectivamente (el propósito principal es separarlos)
- Luego viene la operación clave: use el nuevo eor' para XOR todos los elementos de la matriz cuyo bit es 1. Este paso es igual al de la pregunta 1.2, el resultado debe ser a o b, suponemos eor' = a . Finalmente, use eor' ^ eor para obtener otro número impar, a saber, 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;
}
La función de eor & (~eor + 1) en el código es obtener el último 1 de la cadena binaria de destino y todos los 0 después de él.
Suponiendo que eor es 1010111100,
podemos usareor & (~eor + 1)
este binario más a la derecha que puede extraer este número ( eor) 1 y valores posteriores, es decir, 100