从零学算法(LCR 190. 加密运算)

计算机安全专家正在开发一款高度安全的加密通信软件,需要在进行数据传输时对数据进行加密和解密操作。假定 dataA 和 dataB 分别为随机抽样的两次通信的数据量:
正数为发送量
负数为接受量
0 为数据遗失
请不使用四则运算符的情况下实现一个函数计算两次通信的数据量之和(三种情况均需被统计),以确保在数据传输过程中的高安全性和保密性。
示例 1:
输入:dataA = 5, dataB = -1
输出:4

  • 实际上这就是不能用四则运算实现加法。那么我们肯定是要先枚举查看各种情况和什么位运算比较符合。将两个数转为二进制后,最后一位分别为 0 或 1,有四种配对可能性(类似数字电路真值表),由于会两个 1 相加会进位,所以我们把结果的和分为不进位n和以及进位和c(不算权重)
a b n c
0 0 0 0
0 1 1 0
1 0 1 0
1 1 0 1
  • 如果不习惯可以看成比如十进制的 8 和 9 相加,会得到 n 为 7,c 代表了进位的 1,由于是十进制,所以实际上表示 1 x 10 = 10,你会发现 a + b 就这样被转换成了 n + c(该例子应该很好理解,两个个位数相加,结果就是和的个位+十位)
  • 根据规律发现 n 为 a^b ,c 为 a&b ,由于权重问题所以 c 实际上是 (a&b)<<1。所以我们不断将 a,b 更新为 n,c 进行累加即可,建议举个例子计算一遍,观察 ab 的变动,比如 8+9,你会发现能够得到 2 的 n 次 c,c 为小于 17 的最大的 2 的 n 次 16,n 为 1。
  •   public int add(int a, int b) {
          while(b != 0) { // 当进位为 0 时跳出
              int c = (a & b) << 1;  // 暂存进位和,c = 进位
              a ^= b; // a = 非进位和,a 更新为 n
              b = c; // b = 进位,b 被操作完了,可以更新为 c 了
          }
          return a;
      }
    
  • 或者写成递归版本
  •   public int add(int a, int b) {
          if(b == 0) return a;
          if(a == 0) return b;
          return add(a^b, (a&b)<<1);
      }
    

你可能感兴趣的:(算法学习,#,位运算,算法)