IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 【每日一题】二进制求和---位运算(图解) -> 正文阅读

[数据结构与算法]【每日一题】二进制求和---位运算(图解)

题目描述

在这里插入图片描述
题目简单明了,我们直接给题解。

常规解法

在这里插入图片描述

在这里插入图片描述
看上图:
很明显我们直到,二进制运算对2取余就是当前位,除于2就是进位。
比如: 0+0=0;进位为0,当前位为0;
0+1=1;进位位0,当前位为1;
1+1=10;进位为1,当前位为0;
从后往前运算,每次从a和b各取一个数字和进位相加;每次得到的当前位的结果,拼接起来,进位放在下一位运算。

            ans.append(sum % 2);
            //除二为进位
            ca = sum / 2;

如果一个字符串已经运算完,另一个还没有运算完,就将已经运算玩的哪的二进制设位0,进行运算,

            //i>0 代表a没遍历完,就让a等于它本来的值,否则就等于0
            sum += i >= 0 ? a.charAt(i) - '0' : 0;
            sum += j >= 0 ? b.charAt(j) - '0' : 0;

最后当两个都遍历完,如果进位位1,就将其拼接起来。最后将所拼接的字符串反转就是我们所得的结果。

代码:

public static String addBinary2(String a, String b) {

        //定义一个StringBuilder用来拼接结果
        StringBuilder ans = new StringBuilder();

        //初始化进位为0,
        int ca = 0;
        //直到两个字符串都遍历完为止
        for (int i = a.length() - 1, j = b.length() - 1; i >= 0 || j >= 0; i--, j--) {
            //sum = ca + a + b
            int sum = ca;
            //i>0 代表a没遍历完,就让a等于它本来的值,否则就等于0
            sum += i >= 0 ? a.charAt(i) - '0' : 0;
            sum += j >= 0 ? b.charAt(j) - '0' : 0;
            //结果是对二取余数
            ans.append(sum % 2);
            //除二为进位
            ca = sum / 2;
        }
        //遍历完如果进位为1,就将一加到后面
        ans.append(ca == 1 ? ca : "");
        //最后对字符串进行反转
        return ans.reverse().toString();
    }

位运算

首先我们先说一下:

位运算加法是用异或 ^:
相同为0,不同为1
0 ^ 0 结果为0
0 ^ 1 结果为1
1 ^ 1 结果为0,因为进位了
进位用and也就是与运算&
只有同时为1是才为1
0 & 0 结果为0
0 & 1 结果为0
1 & 1 结果为1

首先看图解:
在这里插入图片描述

在这里插入图片描述

首先初始化一个字符数组,长度为a和b最长的那个+1,因为有可能会有进位。将这和字符数组初始化为全‘0’数组

char[] rs = new char[Math.max(a.length(), b.length()) + 1];
        //将其初始化位0
        for (int i = 0; i < rs.length; i++) {
            rs[i] = '0';
        }

定义两个数组max,min,分别存两个字符串。

char[] max = (a.length() >= b.length() ? a : b).toCharArray();
        char[] min = (a.length() >= b.length() ? b : a).toCharArray();

将短的那个赋值给我们定义字符数组

//将短的赋给rs
        for (int i = 0; i < min.length; i++) {
            rs[rs.length - 1 - i] = min[min.length - 1 - i];
        }

然后max和re从后往前逐位进行运算

int carry = 0;
        //诸位进行运算
        for (int i = 0; i < max.length; i++) {

            int left = rs[rs.length - 1 - i] == '0' ? 0 : 1;
            int right = max[max.length - 1 - i] == '0' ? 0 : 1;

            int v = left ^ right ^ carry;
            carry = (left & right) + ((left ^ right) & carry);

            rs[rs.length - 1 - i] = v > 0 ? '1' : '0';

        }

最后将carry放在第一位即可

//进位大于一 就加个一
        if (carry > 0) {
            rs[0] = '1';
            return new String(rs);
        } else {
            rs[0] = ' ';
            return new String(rs).trim();
        }

最后关于其中位运算代码,在作以解释

int v = left ^ right ^ carry;

异或可以进行多位运算,等同于加法。
可以计算作为验证

 carry = (left & right) + ((left ^ right) & carry);

计算进位
对于left & right(left ^ right) & carry
他们两个的结果不可能同时为1,大家可以自己运算。
我们讲讲为什么要这么算进位
当不算进位,两个数都为0的时候,不论进位值为几,这几个数相加都不可能产生进位。left & right(left ^ right)都为0,所以与carry无关。
当两个同时为1时一定产生进位,左边已经为1,但(left ^ right)为0,与进位无关。所以最后的进位结果是1;
当两个数一个为0一个为1时,加号左边为0,(left ^ right)为1,此时与carry有关,当carry为1,时会产生进位,当carry为0时不产生进位,所以时&carry。

完整代码:

//初始话一个最大长度+1的字符数组,因为最后可能产生进位,所以加一
        char[] rs = new char[Math.max(a.length(), b.length()) + 1];
        //将其初始化位0
        for (int i = 0; i < rs.length; i++) {
            rs[i] = '0';
        }
        //max等于长的字符串,min等于短的字符串
        char[] max = (a.length() >= b.length() ? a : b).toCharArray();
        char[] min = (a.length() >= b.length() ? b : a).toCharArray();
        //将短的赋给rs
        for (int i = 0; i < min.length; i++) {
            rs[rs.length - 1 - i] = min[min.length - 1 - i];
        }

        int carry = 0;
        //诸位进行运算
        for (int i = 0; i < max.length; i++) {

            int left = rs[rs.length - 1 - i] == '0' ? 0 : 1;
            int right = max[max.length - 1 - i] == '0' ? 0 : 1;

            int v = left ^ right ^ carry;
            carry = (left & right) + ((left ^ right) & carry);

            rs[rs.length - 1 - i] = v > 0 ? '1' : '0';

        }
        //进位大于一 就加个一
        if (carry > 0) {
            rs[0] = '1';
            return new String(rs);
        } else {
            rs[0] = ' ';
            return new String(rs).trim();
        }

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-12-14 16:12:59  更:2021-12-14 16:13:23 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 16:32:26-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码