[Estructura de datos e implementación del algoritmo C++] 1. Uso de XOR

El video original es la enseñanza de la estación B de Zuo Chengyun.



XOR: 0 si son iguales, 1 si son diferentes. Una mejor forma de recordar: sumar sin llevar

  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,
Por favor agregue una descripción de la imagen
podemos usar eor & (~eor + 1)este binario más a la derecha que puede extraer este número ( eor) 1 y valores posteriores, es decir, 100
Por favor agregue una descripción de la imagen

Supongo que te gusta

Origin blog.csdn.net/Motarookie/article/details/131335055
Recomendado
Clasificación