算法 —— 位运算

目录

位运算常用结论

位运算例题

位1的个数

比特位计算

 汉明距离

只出现一次的数字

判定字符是否唯一

丢失的数字

两整数之和

 消失的两个数字

进制转换


位运算常用结论

想详细了解位运算的内容可以阅读我的这篇博客:应该背下的位运算

以下我只介绍一些位运算的常用结论:

1、基础位运算:我们只需要记住以下口诀:

  1. &按位与:有0就是0
  2. | 按位或:有1就是1
  3. ^ 按位异或:相同为0,相异为1 / 无进制相加(两个1相加不向高处进位)

2、给一个数n,确定它的二进制表示中的第 x 位是0还是1

        ( n >> x ) & 1

3、将一个数n的二进制表示的第 x 位修改成1

        n | = ( 1 << x ) 

4、将一个数n的二进制表示的第 x 位修改成0

        n & = ( ~ ( 1 << x ) )

5、提取一个数n的二进制表示中最右侧的1

        n & -n

6、干掉一个数n的二进制表示中最右侧的1

        n & ( n - 1 )

7、异或运算律

  1. a ^ 0 = a
  2. a ^ a = 0
  3. a ^ b ^ c  = a ^ ( b ^ c )

位运算例题

位1的个数

利用上述第二个结论即可AC,代码如下:

class Solution {
public:int hammingWeight(int n) {int count = 0;while (n){if (n & 1)count++;n >>= 1;}return count;}
};

比特位计算

 这里为了减小时间复杂度,我们利用动态规划进行完善,代码如下:

class Solution {
public:vector<int> countBits(int n) {vector<int> ret(n + 1, 0);for (int i = 1; i <= n; i++){if (i % 2) // 如果是奇数,那么就是前一个偶数的所有的1加1ret[i] = ret[i - 1] + 1;else // 如果是偶数,那么则等于它除二后的个数ret[i] = ret[i / 2];}return ret;}
};

为什么这里能用动态规划解决呢?好好思考一下,一个偶数变成一个奇数需要加一或者减一,在二进制上最直观的表现是最低位是否为1,如果为1那么就是奇数,如果为0那么就是偶数,这样就能够解释if语句里的内容了。

那么else语句中是什么意思呢?以6,3为例,6的二进制为110,3的二进制为11,二进制里的计算方式是一个二项式定理,这里不难发现,6是从3这样变化而来的:
2^{2}+2^{1} = \left ( 2^{1} + 2^{0} \right )*2


 汉明距离

两个数异或一下就能判别出所有1的二进制位,代码如下:

class Solution {
public:int hammingDistance(int x, int y) {int tmp = x ^ y, count = 0;while (tmp){if (tmp & 1)count++;tmp >>= 1;}return count;}
};

只出现一次的数字

LeetCode —— 只出现一次的数字


判定字符是否唯一

大家先看一下我之前写的代码:

class Solution {
public:bool isUnique(string astr) {sort(astr.begin(), astr.end());for (int i = 1; i < astr.size(); i++)if (astr[i] == astr[i - 1])return false;return true;}
};

 直接排序加比较,时间复杂度稍微有些高,我们用位运算看能不能一次遍历就能找到正确答案:

class Solution {
public:bool isUnique(string astr) {// 比26字母表还大说明必定有重复if (astr.size() > 26)return false;int bitMap = 0;for (auto& ch : astr){int tmp = ch - 'a';// 如果位图中的这一位存在了就说明已出现过if ((bitMap >> tmp) & 1)return false;// 第一次出现的加入到位图中bitMap |= (1 << tmp);}return true;}
};

这里我们使用一个int类型的变量来存值,可以存32个比特位,二进制位为0表示没出现,1为出现


丢失的数字

由于本题元素是一个等差数列,可以用求和公式直接计算出正常序列的和, 我们也可以用位运算解决这个问题,利用相同数字异或为0的结论即可AC,代码如下:

class Solution {
public:int missingNumber(vector<int>& nums) {int ret = 0;for (int i = 1; i <= nums.size(); i++)ret ^= (i ^ nums[i - 1]);return ret;}
};

两整数之和

这里又需要一个新的结论:进位,两个数进行按位与运算,如果有进位就左移一位

比如101和110相加,得到1011。最低位和第一位按位与之后变成0,第二位按位与后变成1,说明他是两个1相加的,意味着要进位,所以向左移动一位。

在文章最开始提到,异或运算是无进制相加,意味着它只能识别不要进位的那些二进制位,这时候我们把进位和异或运算结合在一起就可以实现不用加减运算符达到两整数之和的目的。

 以13+28为例,我们可以看到此方法可行,具体代码如下:

class Solution {
public:int getSum(int a, int b) {while (b){int tmpa = a, tmpb = b;a = tmpa ^ tmpb; b = (tmpa & tmpb) << 1;}return a;}
};

 消失的两个数字

 本题用到了丢失的数字和只出现一次的数字里的知识,内容可看链接。

这里我们可以想象为正常序列和缺少的两个数字的缺失序列并在一起的大序列,其中有两个数字出现了一次,另外数字出现了两次,那么就可以进行分组。

我们把所有数字异或在一起,得到缺失两个数字异或的值,由于两个数字异或不可能等于0,所以他们最少有一个位不同,异或后的那个值1的最低位就是不同位,以这个为判定标准进行分组,代码如下:

class Solution {
public:vector<int> missingTwo(vector<int>& nums) {int tmp = 0; // tmp是缺失两个数异或得到的结果for (int i = 1; i <= nums.size() + 2; i++)tmp ^= i;for (auto& n : nums)tmp ^= n;vector<int>ret(2, 0); // 存放缺失的两个数int lowbit = tmp & -tmp; // 找到比特位为1的最低位for (auto& e : nums)// 分两组  ret[(e & lowbit) != 0] ^= e; // 注意加括号for (int i = 1; i <= nums.size() + 2; i++)ret[(i & lowbit) != 0] ^= i;return ret;}
};

进制转换

本题就不再是二进制位运算的解决方法了,很显然要解决这种题型首先要了解进制转换的规则:

n进制位转换成十进制位不用多说,一个求和累加公式即可,那么10进制转换为2进制怎么做呢?

我们利用不断除n得到余数,最后余数逆置就是转换后的结果,如图23从十进制转换为二进制,通过这个特性可以用代码来进行实现。

#include<bits/stdc++.h>
using namespace std;int fn, ln; string num, ret;
long long tn, d = 1;int main()
{cin >> fn >> num >> ln;for (int i = num.size() - 1; i >= 0; i--){if (num[i] >= 'A' && num[i] <= 'F')tn += (num[i] - 'A' + 10) * d;elsetn += (num[i] - '0') * d;d *= fn;}while (tn){int tmp = tn % ln; tn /= ln;if (tmp >= 10)ret += (tmp - 10 + 'A');elseret += to_string(tmp);}reverse(ret.begin(), ret.end());cout << ret << endl;return 0;
}

如果出现了基数是负数的情况还能不断除法取余吗,答案是可以的,我们要怎么处理余数为负数的情况呢 ?这是除法运算法则:

被除数 = 商 * 除数 + 余数

当被除数或除数有一者为负数时就会出现余数为负数的情况,我们要避免这个情况发生,只需要将商+1,余数-除数即可,因为余数(绝对值)一定小于除数,所以这样就可以将余数转换为正数:

(商+1)* 除数 +(余数 - 除数)= 商 * 除数 + 除数 + 余数 - 除数 = 商 * 除数 + 余数 =被除数

 按照这个式子可以实现负进制的情况,代码实现如下:

#include<bits/stdc++.h>
using namespace std;
int num, r;
string ret;int main()
{cin >> num >> r; int d = num;while (num){int tmp = num % r;if (tmp < 0){tmp -= r;num += r;}if (tmp >= 10)ret += (tmp - 10 + 'A');elseret += to_string(tmp);num /= r;}reverse(ret.begin(), ret.end());cout << d << '=' << ret << "(base" << r << ')' << endl;return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

3.特征工程-特征抽取、特征预处理、特征降维

文章目录 环境配置&#xff08;必看&#xff09;头文件引用1.数据集: sklearn代码运行结果 2.字典特征抽取: DictVectorizer代码运行结果稀疏矩阵 3.文本特征抽取(英文文本): CountVectorizer()代码运行结果 4.中文文本分词(中文文本特征抽取使用)代码运行结果 5.中文文本特征抽…

Linux基础笔记分享(超详细~)

文章目录 Linux基础1.基础概念2.基础命令命令行快捷键自动补全: tab移动光标快速删除翻看历史命令终止程序退出登录清屏 查看命令帮助alias命令别名-快捷键pwd-类似于地图cd-类似于传送术mkdir-类似于合成装备touch-创建文件ls-类似于查看装备tree-打印目录层级结构cp-复制命令…

HarmonyOS 习题(一)

1、在HarmonyOS系统架构中&#xff0c;以下哪项属于应用层? A&#xff09;AI子系统 B&#xff09;U框架 C&#xff09;电话 D&#xff09;内核 答案&#xff1a;C 解析&#xff1a; 2、在HarmonyOS系统架构中&#xff0c;以下哪项提供统一的外设访问能力和驱动的开发管理框架…

sqli-labs靶场练习(1、5-8关)

自己搭建环境啊喂...http://127.0.0.1/sqli-labs-php7-master/ 第一关 1.单引号判断是否存在注入点 /?id1 2.查询列数 ?id1 order by 3-- ?id1 order by 4-- 由此可判断有3列 3.查询用户名和密码分别在哪列 ?id-1 union select 1,2,3 -- 4.查询数据库名称为security ?…

81.SAP ME - SAP SMGW Getway Monitor

目录 1.起因 2.SMGW Displaying Logged On Clients Displaying Remote Gateways Display and Control Existing Connections Deleting a Connection Displaying Gateway Release Information Displaying Parameters and Attributes of the Gateway Change Gateway Pa…

js中的ajax【Axios,XMLHttpRequest,Promise,async】回调函数地狱等问题

目录 前置知识 1.什么是异步请求&#xff1f; 2.什么是回调函数 3.如何查看网页的异步请求&#xff08;XHR&#xff09;&#xff1f; 4.什么是ajax jquery的ajax&#xff0c;xhr&#xff0c;axios关系 正文---几种请求之间的关系 axios Axios的诞生 Axios的介绍 定义…

Idea绿色下载安装教程-最新,2024版本通用-附下载链接

插件链接&#xff1a; 脚本 Idea下载安装完成后 进入激活码输入页面&#xff0c;然后关闭IDEA 按照下面流程进行激活 1. 按照以下步骤&#xff0c;亲测可用&#xff0c;记得一定要先关闭idea 2. 选择对应软件 3.选择bin、目录对应选项 5.激活 6.成功

ROS2 Humble 学习【openEuler】

ROS2 Humble 学习 1 介绍1.1 概述1.2 ROS2 详细介绍1.3 openEuler 安装 ROS2 Humble1.4 ROS2 系统架构 2 ROS2 基础2.1 节点编写、编译、运行【简单示例】节点编写节点编译 g节点运行节点编译 make节点编译 CMakeLists.txtCMake依赖查找流程Python 依赖查找流程 2.2 节点交互、…

LeetCode | 441 | 排列硬币 | 二分查找

&#x1f64b;大家好&#xff01;我是毛毛张! &#x1f308;个人首页&#xff1a; 神马都会亿点点的毛毛张 今天分享的是LeetCode中一道标签为简单的算法题&#xff0c;本质是一道数学题 文章目录 1.题目描述2.题解2.1 公式解法2.2 暴力解法2.3 二分查找 LeetCode链接&#…

【51单片机仿真】基于51单片机设计的钟表定时闹钟系统仿真源码设计文档演示视频——完整资料下载

演示视频 设计内容 &#xff08;1&#xff09;使用 DS1302 结合字符型 LCD12864 显示器设计一个简易的定时闹钟 LCD 时钟。程序执行后 LCD 显示“00&#xff1a;00&#xff1a;00” &#xff08;2&#xff09;K1—设置现在的时间&#xff0c;年闪烁&#xff0c;再按 K1 键月闪…

15.75.【C语言】表达式求值

目录 一.整型提升 1.定义 2. 一.整型提升 1.定义 C语言中整型算术运算总是至少以缺省&#xff08;默认&#xff09;整型类型的精度来进行的。为了获得这个精度&#xff0c;表达式中的字符和短整型操作数在使用之前被转换为普通整型&#xff0c;这种转换称为整型提升 2.整型提…

njs、nginx JavaScript、在nginx上写JavaScript、nginx支持js

njs、nginx JavaScript、在nginx上写JavaScript、nginx支持js 现在是 2024-08-05 &#xff0c;在一个月前&#xff0c;我逛nginx官网&#xff0c;还没有这个模块的介绍。看njs官网&#xff0c;在四年前已经创建这个项目。不知道是不是近期才把这个项目纳入。以前不知道这模块&…

C# 构建观测者模式(或者为订阅者模型)

前言&#xff1a; 观测者模型的基本理念&#xff0c;就是&#xff0c;我有一个公共的事件&#xff0c;定义好他的事件的触发、数据接口。然后&#xff0c;通过增加订阅者&#xff08;实例&#xff09;来订阅这个事件的&#xff0c;或者说观察这个事件。如果事件发生&#xff0…

未授权访问漏洞系列详解⑥!

JBoss未授权访问漏洞 JBoss是一个基于J2EE的开放源代码应用服务器&#xff0c;代码遵循LGPL许可&#xff0c;可以在任何商业应用中免费使用;JBoss也是一个管理EJB的容器和服务器&#xff0c;支持EJB1.1、EJB 2.0和EJB3规范。,默认情况下访问 http://ip:8080/jmx-console 就可以…

【Java数据结构】---初始数据结构

乐观学习&#xff0c;乐观生活&#xff0c;才能不断前进啊&#xff01;&#xff01;&#xff01; 我的主页&#xff1a;optimistic_chen 我的专栏&#xff1a;c语言 &#xff0c;Java 欢迎大家访问~ 创作不易&#xff0c;大佬们点赞鼓励下吧~ 前言 从今天开始我们就要学习Java…

Altium designer学习笔记03 -原理图绘制

原理图绘制 1. 原理图页大小设置2.原理图格点的设置3. 原理图模板的应用4. 元件的放置5.元件属性的编辑6.元件的选择、移动、旋转、镜像6.1 元件的选择6.2 元件的移动6.3 元件的旋转6.3 元件的镜像 7.元件的复制/剪切/粘贴8.元件的排列与对齐9.绘制导线的导线属性设置10.放置网…

实时数仓分层架构详解

首先&#xff0c;我们从数据仓库说起。 数据仓库的概念可以追溯到20世纪80年代&#xff0c;当时IBM的研究人员提出了商业数据仓库的概念。数据仓库概念的提出&#xff0c;是为了解决和数据流相关的各种问题&#xff0c;特别是多重数据复制带来的高成本问题。 数据仓库之父Bill …

简单反射型XSS的复现

xss反射型攻击&#xff1a; 1.最简单的漏洞复现&#xff1a; 这里我们有一个最简单的网页&#xff1a;由于地址不存在&#xff0c;所以图片加载不出来。 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta…

skynet 连接redis

文章目录 概述main.luaagent.luaredis.lua 小结 概述 之前写过skynet 入门篇&#xff0c;还有skynet实操篇&#xff1b;这2篇&#xff0c;主要写了skynet如何使用&#xff0c;还有些skynet的调用流程之类。 其实&#xff0c;看过skynet的demo之后&#xff0c;发现skynet中没有…

Simulink模型开发中的一些自动化方法

随着Simulink模型的产品化开发进程&#xff0c;许多模型开发人员会关心模型的建模自动化问题。比如如何对模型中的元素进行批量查找和修改&#xff1b;如何构建自己的建模规则对模型进行检查&#xff1b;如何实现测试自动化等。在这些使用场景中我们都需要了解一些Simulink函数…