🎊 一次性搞懂异或^

一次性搞懂异或^

异或(XOR) 是一种基础的位运算,符号为 ^。它针对二进制位进行操作,具有独特的逻辑特性,在算法优化、数据处理、加密等场景中应用广泛。

异或的核心原理

异或是对两个操作数的每一位二进制位进行独立运算,运算规则为:相同为 0,不同为 1

(即:0 ^ 0 = 0,0 ^ 1 = 1,1 ^ 0 = 1,1 ^ 1 = 0)。

示例:

以整数 3(二进制 011)和 5(二进制 101)的异或运算为例:

011 (3)

^ 101 (5)

--------

110 (6)

结果为 6(二进制 110),每一位均遵循 “相同为 0,不同为 1” 的规则。

异或的关键性质

异或的实用价值源于其独特的数学性质,这些性质是解决问题的核心工具:

自反性:x ^ x = 0任何数与自身异或,结果为 0(二进制每一位都相同,均变为 0)。

恒等性:x ^ 0 = x任何数与 0 异或,结果为其自身(二进制每一位与 0 运算,保持原数不变)。

交换律:a ^ b = b ^ a异或运算的顺序不影响结果。

结合律:(a ^ b) ^ c = a ^ (b ^ c)异或运算的分组不影响结果。

还原律:a ^ b ^ b = a一个数连续异或同一个数两次,结果为原数(利用 b ^ b = 0 和 a ^ 0 = a 推导)。

实用价值

不使用临时变量交换两个变量的值

传统交换两个变量需要临时变量(如 int temp = a; a = b; b = temp;),而异或可通过性质 5 实现无临时变量交换:

a ^= b; // a = a ^ b(此时 a 存储两数异或结果)

b ^= a; // b = b ^ (a ^ b) = a(利用结合律和 b^b=0,还原出 a)

a ^= b; // a = (a ^ b) ^ a = b(利用 a^a=0,还原出 b)

明确规定a != b 的时候才行,如果a=b就都清零了。

查找数组中 “只出现一次的数字”

若数组中除一个元素外,其余元素均出现两次,可利用异或的 x ^ x = 0 和 x ^ 0 = x 性质快速找到唯一元素:所有元素异或的结果 = 唯一出现一次的元素(因为成对的元素异或后为 0,0 与唯一元素异或后为其本身)。

leetcode例题

class Solution {

public:

int singleNumber(vector& nums) {

int n = nums.size();

int t = 0;

for(auto x:nums){ t^=x;}

return t;

}

};

翻转二进制中的特定位

若需翻转一个整数的某几位(0 变 1,1 变 0),可利用异或与 “掩码(mask)” 结合:

掩码中需翻转的位设为 1,其余位设为 0;原数与掩码异或后,目标位被翻转,其余位不变(因 x ^ 0 = x)。

示例:翻转 num 的第 k 位(从 0 开始计数):

#include

using namespace std;

int flipBit(int num, int k) {

return num ^ (1 << k); // 1 << k 生成第 k 位为 1 的掩码

}

int main() {

int num = 5; // 二进制 101

int flipped = flipBit(num, 1); // 翻转第 1 位(0 基)

cout << flipped << endl; // 二进制 111(7),第 1 位从 0 变为 1

return 0;

}

判断两个整数是否同号

整数的最高位(符号位):正数为 0,负数为 1。

若两数同号,符号位异或结果为 0(0^0=0 或 1^1=0);若两数异号,符号位异或结果为 1(0^1=1)。

利用这一特性可快速判断同号性:

(a ^ b) >= 0;

>=0就是同号,反之异号。

简单加密与解密

利用异或的 “还原律”(a ^ key ^ key = a),可实现轻量字符加密:

加密:密文 = 明文 ^ 密钥;解密:明文 = 密文 ^ 密钥。

#include

#include

using namespace std;

// 加密/解密函数(同一函数,因异或两次密钥还原)

string xorEncryptDecrypt(const string& data, char key) {

string result = data;

for (char& c : result) {

c ^= key; // 异或密钥

}

return result;

}

int main() {

string plaintext = "Hello, XOR!";

char key = 'k'; // 密钥(任意字符)

string ciphertext = xorEncryptDecrypt(plaintext, key);

cout << "加密后:" << ciphertext << endl; // 乱码

string decrypted = xorEncryptDecrypt(ciphertext, key);

cout << "解密后:" << decrypted << endl; // 输出 Hello, XOR!

return 0;

}

加密后:#GK3$9J

解密后:Hello, XOR!

计算汉明距离

汉明距离是指两个等长字符串(通常是二进制字符串或二进制数)中,对应位置上字符不同的数量。

int hammingDistance(int x, int y) {

int xorResult = x ^ y; // 不同的位为1

int distance = 0;

// 统计1的个数(汉明重量)

while (xorResult) {

xorResult &= xorResult - 1; // Brian Kernighan算法

distance++;

}

return distance;

}

点击学习Brian Kernighan算法

总结

异或运算高效简洁,并且有多种妙手

🎁 相关推荐

卡漫初级
🎯 365bet体育在线导航

卡漫初级

📅 01-23 👀 1034
购买和出售 Nixon 手表
🎯 365bet体育在线导航

购买和出售 Nixon 手表

📅 07-18 👀 5712
有实力的艾灸培训服务哪个好,剖析课程内容与教学方式
🎯 365bet体育在线导航

有实力的艾灸培训服务哪个好,剖析课程内容与教学方式

📅 01-23 👀 2677