这是第 16篇算法,力扣链接
计算机安全专家正在开发一款高度安全的加密通信软件,需要在进行数据传输时对数据进行加密和解密操作。假定
dataA
和dataB
分别为随机抽样的两次通信的数据量:
- 正数为发送量
- 负数为接受量
- 0 为数据遗失
请不使用四则运算符的情况下实现一个函数计算两次通信的数据量之和(三种情况均需被统计),以确保在数据传输过程中的高安全性和保密性。
示例 1:
输入:dataA = 5, dataB = -1 输出:4
如题,不让做四则运算,那就一定不是十进制的加法,这里就要设计到上次算法题的知识了,回顾一下不同符号的计算规则:
符号 | 描述 | 运算规则 |
---|---|---|
^ | 异或 | 两位不相同,结果为1 |
& | 与 | 两位都是1,结果为1 |
接着回顾一下二进制的计算规则。
首先二进制实际上是没有减法运算的,所谓减法就是符号为不为 0,因此,二进制进行的都是加法运算。
其次加法规则就是 0 + 1 = 1、1 + 1 = 0、0 + 0 = 0 显然 这是一个异或运算。
值得注意的是,这里当且仅当 1 + 1 = 0 发生了进位运算,进没进位可以通过与运算来判断。
因此,解题思路如下:
先考虑没进位的场景的值,即: dataA ^ dataB
然后计算出进位的值,即:dataA & dataB
把进位的值左移一下,让它真的去进位,即:(dataA & dataB) << 1
把这个进位的值赋值给B,异或的结果赋值给A,再来一遍循环,知道进位的值为0为止。
代码如下:
func encryptionCalculate(dataA int, dataB int) int {
for dataB != 0 {
temp := dataA ^ dataB
dataB = (dataA & dataB) << 1
dataA = temp
}
return dataA
}
当然,迭代能做递归也能做,先设置出口:
if dataA == 0 || dataB == 0 {
return dataA ^ dataB
}
然后递归逻辑其实和迭代一样,修改 AB 的值,如下:
encryptionCalculate(dataA^dataB, (dataA&dataB)<<1)
代码如下:
func encryptionCalculate(dataA int, dataB int) int {
if dataA == 0 || dataB == 0 {
return dataA ^ dataB
}
return encryptionCalculate(dataA^dataB, (dataA&dataB)<<1)
}