算法--位运算和模拟

AD7768与STM32F439的硬件设计避坑指南:如何优化高精度ADC系统的电源与PCB布局 本文详细解析了AD7768与STM32F439在高精度ADC系统硬件设计中的关键问题与优化方案。从电源系统设计、PCB布局到基准电压选型,提供了实用的避坑指南和实测数据,帮助工程师提升系统性能至110dB动态范围。特别强调了SPI信号布线和电源滤波对ADC精度的重要影响。 阅读详情

常见位运算总结

1、基础位运算:^ --> 相同为0,相异为1/ 无进位相加
2、给一个数n,确定它的二进制表示中的第x位是0还是1:(n >> x)&1,结果为0说明第x位是0,结果为1说明第x位为1;或者 n&(1<<x) 结果不为0也可以说明第x位为1
3、将一个数n的二进制表示的第x位改成1:n = n | (1<<x)
4、将一个数n的二进制表示的第x位改成0:n = n &( ~(1<<x))
5、提取一个数n二进制表示中最右侧的1:n = n & (-n),其中-n是将最右侧的1,左边的区域全部变成相反数
6、去除一个数n二进制表示中最右侧的1:n = n & (n-1),其中n-1是将最右侧的1已经右边的部分全部变相反。
7、异或运算的运算律:a ^ 0 = a,a ^ a = 0,a ^ b ^ c = a ^ (b ^ c)。

例题一:两整数之和

1、分析:题目要求简单明了,但是不让我们使用加减符号还要返回两整数之和,那我们可以考虑用异或位运算,不过异或的结果并没有考虑进位,所以我们还要计算出两整数相加的进位情况,这个可以借助与运算来解决,下面给出图示方便理解:

class Solution {
public:
    int getSum(int a, int b) {
        int ret = a^b;
        unsigned int And = ((unsigned int)(a&b))<<1;//(a&b)=-1再左移到符号位属于未定义行为
        while(And)
        {
            int tmp = ret;//下面的And里面的ret不能是更新后的
            ret = ret ^ And;
            And = ((unsigned int)(tmp & And))<<1;
        }
        return ret;
    }
};

例题二:只出现一次的数字II

1、分析:这道题可以用位图的思想尝试解决:因为只有一个数是只出现一次,其他都是三次,那么我们从所有的数结合在一起来看,是不是32位bit位图里,每一个bit位是1的总数一定是3n+1(只出现一次的数的这个bit位是1)或者3n(只出现一次的数的这个bit位是0),那么我们可以遍历nums数组,计算每一个bit位的1的总数目,然后去模3,如果结果是1,是不是可以说明只出现一次的数的这个bit位是1。
2、代码:

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        //计算所有数32个比特位每一个比特位的总和,%3==1,single对应比特位为1
        int ret = 0;
        for(int i =0;i<32;i++)
        {
            int sum =0;
            for(auto x:nums)
            {
                //计算1的个数
                if(((x>>i)&1)==1)
                    sum++;
            }
            if(sum%3==1)
            {
                ret = ret|(1<<i);
            }
        }
        return ret;
    }
};

例题三:消失的两个数字

1、这道题虽然是困难题,但是如果做过这两道题:260.只出现一次的数字III 和 268.丢失的数字
那这道题还是很简单的。

将nums数组所有元素和1到nums.size()+2的数字异或得到只出现一次的a^b,因为a和b不相同,一定可以在异或结果找到为1的比特位,再根据这个比特位将所有数分成两部分,分别再异或一次,就可以把a和b给区分开了。

2、代码:

class Solution {
public:
    vector<int> missingTwo(vector<int>& nums) {
        int xorall = 0;
        for(auto e:nums) xorall^=e;
        for(int i =1;i<=nums.size()+2;i++)
        {
            xorall^=i;//缺的两个数的异或结果
        }
        //找到xorall哪一个比特位为1
        int lowbit = 0;
        while(1)
        {
            if(((xorall>>lowbit)&1)==1) break;
            lowbit++;
        }
        int a = 0,b=0;
        //根据lowbit将nums和【1,nums.size()+2】分成两部分
        for(auto e:nums) 
        {
            if(((e>>lowbit)&1)==1) a^=e;
            else b^=e;
        }
        for(int i =1;i<=nums.size()+2;i++)
        {
            if(((i>>lowbit)&1)==1) a^=i;
            else b^=i;
        }
        return {a,b};
    }
};

模拟

例题一:提莫攻击

1、分析:看了示例1大概可以明白这道题需要我们做什么,我们可以抽象成一个数轴:如果b-a>=duration,是不是就是第b秒之前就执行完duration秒,中毒时间要加duration;如果b-a<duration,就相当于没有中毒duration秒就再次中毒,那中毒时间要加b-a秒,之后再从第b秒开始计算中毒时间。最后一次中毒因为不需要判断差值,所以就直接加上duration。

2、代码

class Solution {
public:
    int findPoisonedDuration(vector<int>& timeSeries, int duration) {
        int ret = 0;
        for(int i= 0;i<timeSeries.size()-1;i++)
        {
            int x = timeSeries[i+1]-timeSeries[i];
            if(x>=duration) ret+=duration;
            else ret+=x;
        }
        ret+=duration;
        return ret;
    }
};

例题二:Z字形变换

1、分析:这道题需要我们将输入字符先排成Z字形,然后再从左往右依次读取字符形成新的字符串,如果我们直接进行模拟,就需要创建矩阵,把字符串的字符按照一定顺序放入矩阵,之后再把矩阵的字符一一读取形成新的字符,假设这个矩阵有len列,这样做时间复杂度和空间复杂度是O(n*len)。

我们可以观察这个矩阵得出规律,下面不用具体例子,用下标来模拟上面这个过程,然后再得出规律,看是否能降低时间复杂度和空间复杂度:


上图n=4,观察第一行:是不是第一行的公差是6,这个公差可以由2*n-2得到;最后一行从下标3开始,就是n-1,公差也是6;第二行根据红色连线,应该是先有(1,6-1),然后(1+6,6-1+6)得到(7,11);第三行也是如此。可以初步得出规律:
(1)第一行:0->0+d->0+2d->....
(2)最后一行:n-1->n-1+d->n-1+2d->....
(3)其它行(假设第 i +1行):(i,d-i)->(i+d,d-i+d)->(i+2d,d-i+2d)->....
单看n = 4这个规律可能不够准确,可以再对照n=3,会发现也符合上述规律。
每一行的边界条件都是不要超过输入字符串长度,并且在写其它行代码时的判断条件有两个,可以看代码实现。

class Solution {
public:
    string convert(string s, int numRows) {
        //处理边界情况
        if(numRows==1) return s;
        int d = 2*numRows-2;
        string ret;
        for(int i=0; i<numRows; i++)
        {
            //处理第一行和最后一行
            if(i==0||i==numRows-1)
            {
                int a= 0;
                while(i+a*d<s.size())
                {
                    ret.push_back(s[i+a*d]);
                    a++;
                }
            }
            //处理中间行
            else
            {
                int a= 0;
                while(i+a*d<s.size())
                {
                    ret.push_back(s[i+a*d]);
                    if(d-i+a*d<s.size())
                    ret.push_back(s[d-i+a*d]);
                    a++;
                }
            }
        }
        return ret;
    }
};

例题三:外观数列

1、分析:这道题是需要我们从1到n,每一次都对前一个数组的元素情况进行概括,就比如前一个数组是[3,3,3,1,1,4,5,5],那我们要做的就是遍历这个数组得出有3个3,2个1,1个4和2个5,然后把这些数字3 3 2 1 1 4 2 5放入新数组,直到遍历了n次。那我们是不是可以借助双指针,由left和right来找到含有相同数字的连续区间,并计算个数。
2、代码细节:注意每次遍历前一个数组,right都不能超过前一个数组的大小;还要注意right越界时是没有计算[left,right-1]连续区间的个数的,所以后面还需要再单独计算一次。
 

class Solution {
public:
    string countAndSay(int n) {
        string v1 = "1";
        //执行n-1次
        for(int i = 2;i<=n;i++)
        {
            string tmp;
            int left = 0,right=0;
            while(right<v1.size())
            {
                if(v1[left]==v1[right]) right++;
                else
                {
                    tmp+= to_string(right-left)+v1[left];
                    left = right;
                }
            }
            tmp+= to_string(right-left)+v1[left];
            v1=tmp;
        }
        return v1;
    }
};

例题四:数青蛙

1、分析:这道题我们单看题目和示例可能没有头绪,那现在举个例子借助一个hash表:croakOfFrogs={c r c o a k r o a k c r o a k},从下标0的 c 开始,走到 r 时是不是需要看一下前面有没有 c 的出现,如果出现我们可以让hash表 c 的个数--, r 的个数++;走到 o 时是不是需要看一下前面有没有 r 的出现,如果出现我们可以让hash表 r 的个数--, o 的个数++;也就是说遇到' r o a k '都得往前看,有没有它们对应的前缀字母,如果没有是不是就不符合条件直接返回-1了。对于c 就比较特殊,因为题目是要不同青蛙的最少数目,如果遍历到 c 时,k已经不为0了,可以认为已经有一只青蛙叫完"croak"了,那我是不是可以让它重新再来一次,也就是让hash表里 k 的个数--。
这里遍历完数组,也不能直接return k,还要检查“c r o a”的个数是不是都为0,为0字符串才有效。
2、代码实现:可以直接用if...else...把五个字母分开;也可以用数组模拟hash表,但是需要一个map表记录每个字母和下标对应关系,方便hash直接映射

class Solution {
public:
    int minNumberOfFrogs(string croakOfFrogs) {
        int c=0, r= 0, o = 0,a=0,k=0;
        for(auto e:croakOfFrogs)
        {
            if(e=='c')
            {
                if(k>0)
                {
                    k--;
                    c++;
                }
                else c++;
            }
            else if(e=='r')
            {
                if(c==0) return -1;
                else
                {
                    c--;
                    r++;
                }
            }
            else if(e=='o')
            {
                if(r==0) return -1;
                else
                {
                    r--;
                    o++;
                }
            }
            else if(e=='a')
            {
                if(o==0) return -1;
                else
                {
                    o--;
                    a++;
                }
            }
            else if(e=='k')
            {
                if(a==0) return -1;
                else
                {
                    a--;
                    k++;
                }
            }
        }
        if(c||r||o||a) return -1;
        return k;
    }
};


 

class Solution {
public:
    int minNumberOfFrogs(string croakOfFrogs) {
        string t = "croak";
       vector<int> hash(t.size());
        unordered_map<char,int> map;
        int i = 0;
        //将五个字母和下标映射
        for(auto e:t)
        {
            map[e]= i++;
        }
        for(auto e: croakOfFrogs)
        {
            if(e == 'c')
            {
                if(hash[t.size()-1] > 0) 
                {
                    hash[t.size()-1]--;
                }
                hash[0]++;
            }
            else
            {
                if(hash[map[e]-1] > 0)
                {
                    hash[map[e]-1]--;
                    hash[map[e]]++;
                }
                else return -1;
            }
        }
        for(int i = 0; i < t.size()-1; i++)
        {
            if(hash[i]) return -1;
        }
        return hash[t.size()-1];
    }
};

NVIDIA Isaac GR00T N1 人形机器人强化学习入门教程(二)详细步骤 LeRobot 格式 1.1 加载数据集 要加载数据集,我们需要定义以下 3 项内容: 在数据中显示图像帧 我们还可以对 LeRobotSingleDataset 类中的数据进行一系列转换。下面展示了如何对数据进行转换。 现在看看应用转换后的数据有何不同。 例如,对状态和操作进行规范化和串联,对视频图像进行裁剪、调整大小和颜色抖动。 二、GR00T 推断 本教程介绍如何使用 GR00 阅读详情

相关推荐

3步搞定专利数据爬取:用Selenium绕过国家知识产权局反爬(附完整代码)

本文详细介绍了3种高效获取专利数据的技术方案,重点解析了使用Selenium绕过国家知识产权局反爬的实战方法,并提供了完整代码示例。文章还探讨了Requests+lxml轻量级方案和混合技术策略,帮助开发者根据需求选择最佳数据爬取方案,特别适合需要专利统计数据的开发者参考。

weixin_29029995的博客 1110

位运算模拟乘法,模指数运算

1. 整数乘法(位运算) 使用位运算模拟乘法,其遵照以下的数学原理,即: ab=a(b020+b121+⋅⋅⋅+bn−12n−1)=a(b020)+a(b121)+⋅⋅⋅+a(bn−12n−1) ab=a(b_02^0+b_12^1+···+b_{n-1}2^{n-1}) \\ \quad=a(b_02^0)+a(b_12^1)+···+a(b_{n-1}2^{n-1}) ab=a(b0​20+...

qq_16215221的博客 963

AnolisOS网卡驱动源码编译与安装实战指南

本文提供了一份详尽的AnolisOS网卡驱动源码编译与安装实战指南。针对系统自带通用驱动不兼容导致网络无法使用的问题,文章从环境准备、源码获取、编译安装到新旧驱动替换与持久化配置,一步步解析了如何通过源码编译安装官方驱动,解决硬件兼容性问题,并确保驱动在系统重启后自动生效。

weixin_28358083的博客 304

史上最详细的位运算实现位图结构,带你单步模拟运行,还看不懂来打我!

抛砖引玉 先来看一道普通的算法题: 有 100 个 10 以内(不含10)的整数,搜索出重复出现次数最多的数字。 看到这种题,搜索重复次数最多的数字,很明显,定义计数器嘛。先统计 1 出现的次数,再统计 2 出现的次数,再统计 3 出现的次数 … 恭喜你!可以回去等通知了… 当然也有人会说,先排序再统计呀,搜索的时间会快一点… 没错,但是,可能还是需要回去等通知 !!! o(╥﹏╥)o 这里,给大家提供一种思路:数组的索引 我们可以尝试着创建一个 length 为 10 的数组 arr,然后 for 循

新青年1号 634

工业焊缝缺陷检测实战:我用PatchCore在自建数据集上踩过的那些坑

本文详细介绍了PatchCore算法在工业焊缝缺陷检测中的实战应用,包括数据准备、模型调参和阈值优化等关键环节。通过分析焊缝图像的特殊性和anomaly detection技术的优化策略,分享了在自建数据集上提升检测精度的实用经验,为工业质检领域提供有价值的参考方案。

weixin_42624889的博客 397

DFT设计绪论

DFT设计的主要目的是为了将defect-free的芯片交给客户。 产品质量,通常使用Parts Per million(PPM)来衡量。 但是随着IC从SSI到VLSI的发展,在test上花销的时间越来越多,test的quality却很难提高,这使得DFT的engineer不断的发展着DFT的技术。 DFT engineer面对的第一个问题是设计内部的状态的可测试性问题。在...

ahr7882的博客 1195

NOIP模拟-----位运算

题目 有q次操作,每次操作是以下两种: 1、 加入一个数到集合中 2、 查询,查询当前数字与集合中的数字的最大异或值,最大and值,最大or值 输入 第一行1个正整数Q表示操作次数 接下来Q行,每行2个数字,第一个数字是操作序号OP(1,2),第二个数字是X表示操作的数字 输出 输出查询次数行,每行3...

weixin_30472035的博客 289

出现 Error:Unable to access jarfile xxxx\target\nacos-server.jar 解决方法

Nacos中的 2.x执行步骤如上,如果需要安装下载1.x版本,执行该步骤之后 自动更新下载的是2.x版本 对此如果需要下载安装1.x的版本,可通过如下连接(windows版本)

码农研究僧的博客 5699

二进制位运算模拟所有情况。

给出一个N,就有2^N种不同的

无奈滴微笑 796

YOLOv9改进策略【Neck】| GSConv+Slim Neck:混合深度可分离卷积和标准卷积的轻量化网络设计

实时检测器架构的轻量级设计GsConv。

Limiiiing的博客 1364

基于DINO自监督学习对YOLO11 Backbone进行预训练

这PoolHead将获取前一层的输出并应用卷积,然后应用自适应平均池化以将特征图的空间维度减小为固定且一致的大小(1x1)。这是必需的,因为否则空间维度会根据输入的大小而变化,这将使将 DINO 头部附加到主干变得困难,因为它需要固定的输入大小。在本指南中,我们将介绍如何使用 Lightly 使用 DINO 预训练 YOLO 11主干,以及如何将其重新加载到 Ultralytics 中进行微调。您可以使用不同的大小,例如,640这与 YOLO 中的默认图像大小更一致,但它也会在训练期间消耗更多 VRAM。

如果想成为中心,那么就到中心去吧。 1014

位运算模拟四则运算

某高手位运算模拟四则运算 个人学习用途博客 部分内容摘抄自网络

Cupido 414

励磁电感 Lm 选对了,LLC 才真“高效”:半桥 LLC 效率优化

你有没有遇到过这种 LLC:参数一套下来,ZVS 也有了,波形看着也“挺谐振”,但一上功率——,效率就是死活上不去。我说句直白的:LLC 的“高效”,很大一部分其实是在背后控场。Lm 选小了,励磁电流蹭蹭涨,谐振电流 RMS 变大,导通损耗、开关损耗、整流损耗一起上天;Lm 选太大,又可能把 ZVS 的门槛抬高,轻载掉 ZVS,EMI 也开始作妖。

weixin_43199439的博客 434

额外题目汇总4-回溯算法,贪心,动态规划,图论,并查集,模拟,位运算

额外题目汇总4-回溯算法,贪心,动态规划,图论,并查集,模拟,位运算

get_money_的博客 953

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

【算法】【优选算法】位运算(下)

结合算法题理解位运算

yj20040627的博客 3389

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

算法:位运算

讲解位运算算法,包括常见运算总结,位运算模拟加法,特殊数字的查找等问题

博客网站 https://async-area.com 1434

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

c语言计算三位相加进位算法,为什么位运算可以实现加法(1、 不考虑进位的情况下位运算符中的异或^可以表示+号)(2、 位运算符中的与运算符&和左移运算符<<可以模拟加法中的进位)(3、位运算不仅可以做...

为什么位运算可以实现加法(1、 不考虑进位的情况下位运算符中的异或^可以表示+号)(2、 位运算符中的与运算符&和左移运算符<一、总结1、 不考虑进位的情况下位运算符中的异或^可以表示+号2、 位运算符中的与运算符&和左移运算符<3、位运算不仅可以做加法,还可以做其它的乘法减法等:计算机本质是二进制运算,许多高人和天书都展示了如何用位运算来实现让人纠结却又惊奇的事情。(...

weixin_42513216的博客 409

算法通关村——位运算的应用

位运算的应用

qq_64551104的博客 299

蓝桥杯竞赛向(C/C++语言)之简单算法篇

竟然又水了一集下一期开DFS,剪枝,和回溯 和 字符串算法(不要和博主提一些高级算法 听不懂。。。。。

weixin_62188419的博客 1569

ACM 学习笔记(二) 位运算、并查集、模拟、枚举、递推、递归

题目描述   给定一个未经排序的整数数组,找到最长且连续的的递增序列。 示例 1: 输入: [1,3,5,4,7] 输出: 3 解释: 最长连续递增序列是 [1,3,5], 长度为3。 尽管 [1,3,5,7] 也是升序的子序列, 但它不是连续的,因为5和7在原数组里被4隔开。 示例 2: 输入: [2,2,2,2,2] 输出: 1 解释: 最长连续递增序列是 [2], 长度为1。 注意:数组长度不会超过10000。 初步解题思路   整体思路就是当前数字与上一个数字一个一个对比。然后计数判断最长的递增

小小何先生的学习之旅 538

611B. New Year and Old Property【模拟位运算】

B. New Year and Old Property time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output The year 2015 is almost over.

初涉_代码世界 778

位运算|拆分贪心

lc2835。

No Game No Life 426

【Java算法入门】二进制求和,位运算基础大揭秘!✨

本文介绍了二进制求和问题的三种解决方案:模拟法、位运算法和使用BigInteger类。重点讲解了模拟法的实现步骤,包括字符串处理、进位规则和从低位到高位的计算过程。还提供了位运算法和BigInteger处理大数的代码示例,并比较了各种方法的优缺点。对于算法初学者,本文强调理解二进制运算规则和进位处理是关键,建议优先掌握模拟法以应对不同长度的二进制字符串相加。该问题不仅考察了基本的编程能力,也帮助理解计算机底层运算机制。

红目香薰 1007

(蓝桥杯C/C++)——基础算法(上)

二分法是一种高效的查找方法,它通过将问题的搜索范围一分为二(两边具有明显的区别),迭代地缩小搜索范围,直到找到目标或确定目标不存在。分法适用于有序数据集合,并且每次迭代可以将搜索范围缩小一半。分法本质上也是枚举,但和暴力枚举不同,二分法利用数据结构的单调性减少了很多不必要的枚举,从而极大地提高了效率,一般可以将O(n)的枚举优化到O(logn)。常见的二分类型有:(1)整数二分(2)浮点二分(3)二分答案(最常见)1.研究并发现数据结构(或答案变量)的单调性。

2402_82385099的博客 5862

优选算法 - 3 ( 位运算 && 模拟 && 分治 11000 字详解 )

位运算 && 模拟 && 分治 11000 字详解

weixin_73232539的博客 686

算法——位运算

算法——位运算(C++版)

观则明的博客 349
上一篇: 算法-前缀和
下一篇: 顺序结构二叉树--堆
bugu___
博客等级 码龄2年 63粉丝 28原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值