算法通关村——位运算

news2025/1/22 22:48:25

1. 常见的位运算

1.1 与 &

&:两个数对应的位都是1,那么结果才是1
1 & 1 = 1
1 & 0 = 0;
0 & 0 = 0;

1.2 或 |

|: 只要两个数对应的位有一个1,结果就是1
1 | 1 = 1;
1 | 0 = 1;
0 | 0 = 0;

1.3 异或^

^: 只有两个数的位都一样的时候才是返回0,否则返回1
1 ^ 1 = 0
0 ^ 1 = 1
0 ^ 0 = 0;

1.4 取反 ~

~: 就是取反,如果位是1,取反就是0
~1=0
~0=1

2. 移位运算

左移:<< 全部二进制左移若干位(如果左移一位,就是除以2)
右移:>> 全部二进制右移若干位

3. 位1的个数

位1的个数
编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量)。

3.1 右移

只需要将每一位和1进行与&操作,如果当前位是1,那么就计数
i=0 00000000000000000000000000001011 & …1=1
i=1 00000000000000000000000000000101 & …1=1
i=2 00000000000000000000000000000010 & …1=0
i=3 00000000000000000000000000000001 & …1=1

结果是3

 public int hammingWeight(int n) {
        int count =0;
        for(int i=0;i<32;i++){
            count+=(n>>i)&1;
        }
        return count;
    }

3.2 左移

先设置一个mask之用于左移比较是否位相同
00000000000000000000000000001011 & 1 =0
00000000000000000000000000001011 & 01 = 0
00000000000000000000000000001011 & 001 =0

00000000000000000000000000001011 & 00000000000000000000000000001 = 1
00000000000000000000000000001011 & 000000000000000000000000000001 = 0
00000000000000000000000000001011 & 0000000000000000000000000000001 = 1
00000000000000000000000000001011 & 00000000000000000000000000000001 = 1

 public int hammingWeight(int n) {
       int count =0;
       int mask = 1;
       for(int i=0;i<32;i++){
           if((n & mask) !=0){
               count++;
           }
           mask<<=1;
       }
       return count;
    }

3.3 n&(n-1)

将二进制最后一个1变成0,直到n最后变成0
00000000000000000000000000001011 & 00000000000000000000000000001010 = 00000000000000000000000000001010
count = 1;

00000000000000000000000000001010 & 00000000000000000000000000001001 = 00000000000000000000000000001000
count = 2;

00000000000000000000000000001000 & 00000000000000000000000000000111 =
0000000000000000000000000000000
count =3;

 public int hammingWeight(int n) {
        int count =0;
       while(n!=0){
           n=n&(n-1);
           count++;
       }
       return count;
    }

这种效率也是比较高的,经常使用,前两个位移都是需要遍历32次,而n&(n-1)只需要n为0的时候就退出
在这里插入图片描述

4. 比特位计数

比特位计数
给你一个整数 n ,对于 0 <= i <= n 中的每个 i ,计算其二进制表示中 1 的个数 ,返回一个长度为 n + 1 的数组 ans 作为答案。
输入:n = 2
输出:[0,1,1]
解释:
0 --> 0
1 --> 1
2 --> 10

4.1 右移

这里面的的计算1的个数就可以采用之前的( n>>i ) &1,其中n是当前的值,而i是右移的位数
很显然,因为元素大小是在0-n这个范围内,所以是按照相应下标就可以知道当前的值,那么再次&1比较,然后右移,就可以算出1的个数,然后赋值给数组。

    public int[] countBits(int n) {
        int [] res = new int [n+1];
        for(int i=0;i<=n;i++){
            for(int j=0;j<32;j++){
                res[i] += (i >>j)&1;
            }
        }
        return res;
    }

此方法缺点在于时间耗费比较长,因为每个元素都要遍历右移32次,才能计算1的个数

4.2 位的性质 n&(n-1)

public int[] countBits(int n) {
        int count =0;
        int [] res = new int [n+1];
        for(int i=0;i<=n;i++){
            res[i] = getOneCount(i);
        }
        return res;
    }

    public int getOneCount(int x){
        int count =0;
        while(x!=0){
            x=x&(x-1);
            count++;
        }
        return count;
    }

5. 颠倒二进制位

颠倒给定的 32 位无符号整数的二进制位。

提示:

请注意,在某些语言(如 Java)中,没有无符号整数类型。在这种情况下,输入和输出都将被指定为有符号整数类型,并且不应影响您的实现,因为无论整数是有符号的还是无符号的,其内部的二进制表示形式都是相同的。
在 Java 中,编译器使用二进制补码记法来表示有符号整数。因此,在 示例 2 中,输入表示有符号整数 -3,输出表示有符号整数 -1073741825

5.1 逐位颠倒

一开始想的是直接反转这个二进制数,直接使用Integer的reverse是肯定不行的。
首先先获取到n的最后一位,然后n进行逻辑右移,和reversed反转数进行相加,直到n变成0
00000010100101000001111010011100右移31位,最低位是0
n逻辑右移1位
00000001010010100000111101001110右移30位,最低位是0

 public int reverseBits(int n) {
        int reversed =0;
        int length = 31;
        while(n!=0){
            reversed += (n&1)<<length;
            // 逻辑右移
            n >>>= 1;
            length--;
        }
        return reversed;
    }

6. 两整数之和

两整数之和
给你两个整数 a 和 b ,不使用 运算符 + 和 - ​​​​​​​,计算并返回两整数之和。
输入:a = 2, b = 3
输出:5

6.1 异或+与

2:010
3:011
5:101
可以看出相同为0,不同为1,这是异或,对于不需要进位的部分采用a^b , 但是需要关注首位是0还是1,进位部分就要采用a&b,只有两个都是1的时候才需要进位。

public int getSum(int a, int b) {
        while(b!=0){
            int sign = (a & b) << 1;
            a = a ^ b;
            b = sign;
        }
        return a;
    }

a&b= 010 010 << 1 = 100 sign = 100
a^b= 001 a = 001
b = 100

a&b = 100 & 001 = 000 000<1 =000 sign =0
a^b = 100 ^ 001 = 101 a = 101
b =0
退出

a=101 =5

7. 递归乘法

递归乘法
递归乘法。 写一个递归函数,不使用 * 运算符, 实现两个正整数的相乘。可以使用加号、减号、位移,但要吝啬一些。
输入:A = 3, B = 4
输出:12

7.1 位运算

例如3 * 4,就是3 * 2 ^ 2,也就是3<<2,左移两位
例如1 * 10,就是1 (2+8)就是1 * 2^1+12 ^3 就是1 <<1 +1<<3

先找出两者之间的最小值和最大值,选取最小值作为乘数的原因是次数较少,然后判断min的最右一位是不是1,是1就添加该位到结果中,然后最小值右移一位

 public int multiply(int A, int B) {
       int add = 0;
       int min = Math.min(A,B);
       int max = Math.max(A,B);
       for(int i=0;min!=0;i++){
           if((min & 1) == 1){
               add  += max<< i;
           }
           min >>= 1;
       }
       return add;
    }

例如 1 * 10 min = 1,max = 10, min &1 =1, add = 10 << 0 = 1010=10
min >>1 = 0 退出

例如 3* 4 min = 3 max =4 min & 1= 1 add = 4 << 0 =4
min >> 1 = 01 min & 1= 1 add = 4 + 4 << 1 = 4 + 8 = 12

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/895140.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于Python的微博大数据舆情分析,舆论情感分析可视化系统,可作为Python毕业设计

运行效果图 基于Python的微博大数据舆情分析&#xff0c;舆论情感分析可视化系统 系统介绍 微博舆情分析系统&#xff0c;项目后端分爬虫模块、数据分析模块、数据存储模块、业务逻辑模块组成。 先后进行了数据获取和筛选存储&#xff0c;对存储后的数据库数据进行提取分析处…

如何用轻叶H5制作一份调查问卷

在营销落地页中&#xff0c;问卷类H5是一种制作简单&#xff0c;易于传播的落地页&#xff0c;通过精巧的设计和严密的逻辑设置&#xff0c;问卷类H5的投放效果也是不容小觑的。 问卷类H5在制作中有以下不可缺少的要素&#xff1a; 清晰的标题和简要的说明 标题应该简明扼要地…

Web3 游戏七月洞察:迈向主流采用的临界点?

作者: lesleyfootprint.network 2023 年 7 月&#xff0c;Web3 游戏领域出现了小幅增长&#xff0c;但对于许多项目来说&#xff0c;用户采用仍然是一个持续的挑战。根据 Footprint Analytics 的数据&#xff0c;活跃的区块链游戏数量略有增加&#xff0c;达到 2,471 个。然而…

第三方支付

1、请求学习中心服务创建选课记录 2、请求订单服务创建商品订单、生成支付二维码。 3、用户扫码请求订单支付服务&#xff0c;订单支付服务请求第三方支付平台生成支付订单。 4、前端唤起支付客户端&#xff0c;用户输入密码完成支付。 5、第三方支付平台支付完成发起支付通…

基于国产安路FPGA的数据采集传输子系统设计

分 布 式 数 据 采 集 系 统 的 结 构 如 图 &#xff12; &#xff0e; &#xff11; 所示 &#xff0c; 主 要 有 传 感 器 网 络 、 数 据 采 集 传 输 子 系 统 、 数 据 汇 聚 平 台 、 数 据 采 集 系 统 控 制 终 端 等 部 分 。 &am…

【JavaEE进阶】MyBatis的创建及使用

文章目录 一. MyBatis简介二. MyBatis 使用1. 数据库和数据表的创建2. 创建Mybatis项目2.1 添加MyBatis框架支持2.2 设置MyBatis配置信息 3. MyBatis开发流程4. MyBatis查询数据库测试 三. MyBatis 流程1. MyBatis 查询数据库流程2. MyBatis 框架交互流程图 一. MyBatis简介 M…

最新k8s集群搭建教程

本次安装在vmware虚拟机下开启3台2核2g的Ubuntu20.04系统 master&#xff1a;192.168.192.137 node1&#xff1a;192.168.192.136 node2&#xff1a;192.168.192.138 关闭防火墙 先查看防火墙状态&#xff0c;如果是关闭就不用管 ufw status关闭selinux&#xff0c;如果没有安…

【sgDragSize】自定义拖拽修改DIV尺寸组件,适用于窗体大小调整

核心原理就是在四条边、四个顶点加上透明的div&#xff0c;给不同方向提供按下移动鼠标监听 &#xff0c;对应计算宽度高度、坐标变化 特性&#xff1a; 支持设置拖拽的最小宽度、最小高度、最大宽度、最大高度可以双击某一条边&#xff0c;最大化对应方向的尺寸&#xff1b;再…

Atlas 元数据管理

Atlas 元数据管理 1.Atlas入门 1.1概述 元数据原理和治理功能&#xff0c;用以构建数据资产的目录。对这个资产进行分类和管理&#xff0c;形成数据字典。 提供围绕数据资产的协作功能。 表和表之间的血缘依赖 字段和字段之间的血缘依赖 1.2架构图 导入和导出&#xff1…

前端如何安全的渲染HTML字符串?

在现代的Web 应用中&#xff0c;动态生成和渲染 HTML 字符串是很常见的需求。然而&#xff0c;不正确地渲染HTML字符串可能会导致安全漏洞&#xff0c;例如跨站脚本攻击&#xff08;XSS&#xff09;。为了确保应用的安全性&#xff0c;我们需要采取一些措施来在安全的环境下渲染…

速看!数据同步如何提升数据分析的准确性与效率?

在当今信息化时代&#xff0c;数据已经成为企业的核心资产。然而&#xff0c;随着数据的不断积累和业务的扩展&#xff0c;如何高效地进行数据分析成为了一个亟待解决的问题。本文将介绍一种重要的数据管理技术——数据同步&#xff0c;以及如何利用数据同步提升数据分析的准确…

【python游戏】这年头塔除了拆还能干什么?这款好玩上瘾的塔防游戏,了解一下嘛

目录标题 前言制作准备敲代码1&#xff09;游戏运行主程序2&#xff09;游戏开始界面3&#xff09;游戏进行中界面4&#xff09;游戏暂停界面5&#xff09;炮塔类 效果展示尾语 前言 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! 炮塔防御&#xff08;Tower Defence&#xff…

小技巧:一键套用模板制作家具电子图册

​制作家具电子图册没有设计灵感怎么办&#xff1f; 可以看看小编分享的小技巧&#xff1a;一键套用模板的网站--------FLBOOK,轻轻松松制作一本别具一格的家具电子图册,操作方法非常简单 1.我们点击模板&#xff0c;在搜索框中搜索家具图册&#xff0c;选择自己喜欢的家具图册…

Vue3 setup新特性简单应用

去官网学习→组合式 API&#xff1a;setup() | Vue.js 运行示例&#xff1a; 代码&#xff1a;App.vue <template><div class"home"><img alt"Vue logo" src"../assets/logo.png"><!-- msg 组件传递数据 --><Hell…

团团代码生成器V2.0:一键生成完整的CRUD功能(重磅来袭!)

前言&#xff1a;考虑到在之前的V1.0版本只支持MySQL数据库&#xff0c;有点局限&#xff0c;因为在实际的项目开发中还会用到一个主流的Oracle数据库&#xff0c;所以我在V1.0的版本上进行了增强&#xff0c;新增了对Oracle数据库CRUD功能的生成&#xff0c;使用过程还是和V1.…

【Rust】Rust学习 第十五章智能指针

指针 &#xff08;pointer&#xff09;是一个包含内存地址的变量的通用概念。这个地址引用&#xff0c;或 “指向”&#xff08;points at&#xff09;一些其他数据。Rust 中最常见的指针是第四章介绍的 引用&#xff08;reference&#xff09;。引用以 & 符号为标志并借用…

外网远程连接Linux服务器

文章目录 视频教程1. Linux CentOS安装cpolar2. 创建TCP隧道3. 随机地址公网远程连接4. 固定TCP地址5. 使用固定公网TCP地址SSH远程 转发内网穿透文章. 本次教程我们来实现如何在外公网环境下&#xff0c;SSH远程连接家里/公司的Linux CentOS服务器&#xff0c;无需公网IP&…

【推荐】深入浅出benan的生命周期

目录 1.spring 管理JavaBean的过程&#xff08;生命周期&#xff09; 2.spring的JavaBean管理中单例模式及原型&#xff08;多例&#xff09;模式 2.1 . 默认为单例&#xff0c;但是可以配置多例 2.2.举例论证 2.2.1 默认单例 2.2.2 设置多例 2.2.3单例与多例的初始化的时…

【数学】CF1242 A

Problem - 1242A - Codeforces 题意&#xff1a; 思路&#xff1a; Code&#xff1a; #include <bits/stdc.h>#define int long longusing i64 long long;constexpr int N 2e3 10; constexpr int M 2e3 10; constexpr int mod 998244353; constexpr int Inf 1e1…

Java中级部分

以下内容来源自Java 面试指南 | JavaGuide(Java面试 学习指南)和自己的学习笔记整理&#xff0c;这里我整理了自己比较感兴趣的点&#xff0c;也有助于我自己理解~ 异常 Exception 和 Error 有什么区别&#xff1f; 在 Java 中&#xff0c;所有的异常都有一个共同的祖先 jav…