[Estrutura de Dados e Implementação do Algoritmo C++] 1. Uso de XOR

O vídeo original é o ensino da estação B de Zuo Chengyun



XOR: 0 se forem iguais, 1 se forem diferentes. Uma maneira melhor de lembrar: adicione sem carregar

  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,
Adicione uma descrição da imagem
podemos usar eor & (~eor + 1)esse binário mais à direita que pode extrair esse número ( eor) 1 e valores subseqüentes, ou seja, 100
Adicione uma descrição da imagem

Acho que você gosta

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