算法|2.异或运算

news2024/11/29 2:44:23

算法|2.异或运算

1.不用额外变量交换两个数的值

题意:不用额外变量交换(数组中)两个数的值

解题思路:

  • 使用异或运算的性质

在这里插入图片描述

代码及运行结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kkTo46xE-1685088032675)(F:\typora插图\image-20230526125538881.png)]

2.找到唯一出现奇数次的数字

题意:一个数组中有一种数出现了奇数次,其他数都出现了偶数次,怎么找到并打印这种数

解题思路:

  • 说明:补码的补码即相反数的补码等于原数补码连同符号位取反末尾加
  • 将数组中的数全部异或一遍,得到的即是结果

核心代码:

//arr中,只有一种数出现奇数次
public static void printOddTimesNum1(int[] arr){
    int ero=0;
    for (int cur:arr) {
        ero^=cur;
    }
    System.out.println("出现奇数次的数字分别是:"+ero);
}

测试方法:

说明,本题和下一题均为写对数器,并且测试方法在同一个main方法中写着呢。故下边不再写该部分内容。

//for test
public static void main(String[] args) {

    int[] arr1 = { 3, 3, 2, 3, 1, 1, 1, 3, 1, 1, 1 };
    //        System.out.println("预期结果:"+2);
    printOddTimesNum1(arr1);

    //        int[] arr2={1,1,2,2,2,3,3,3,4,4};
    int[] arr2 = { 4, 3, 4, 2, 2, 2, 4, 1, 1, 1, 3, 3, 1, 1, 1, 4, 2, 2 };
    //        System.out.println("预期结果:"+2+" "+3);
    printOddTimesNum2(arr2);

}

测试结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aOPZG8a5-1685088032675)(F:\typora插图\image-20230526140344898.png)]

3.找到唯二出现奇数次的数字

题意:一个数组中有两种数出现了奇数次,其他数都出现了偶数次,怎么找到并打印这两种数

解题思路:

在这里插入图片描述

  • 拿到最右侧的1:原数与相反数求与
  • 将数组中的数分为两组。分组依据:异或全数组的数据最右侧是否有1
  • 拿到最右侧为1的位置==》体现在一个二进制序列==》十进制数==》利用这个数判断数组中的数这一位是否有1,有则异或到一个ero1,得到其中一个结果
  • 另一个结果通过异或过整组数的ero和ero1再异或可得到

核心代码:

//arr中,有两种数出现奇数次
public static void printOddTimesNum2(int[] arr){
    int ero=0;
    for (int cur:arr) {
        ero^=cur;
    }
    //提取出最右侧的1:原数与相反数相与
    int rightestOne=ero&(-ero);
    //        System.out.println(rightestOne);
    //ero':提取出最右侧为这个1的一组数的结果
    int ero1=0;
    for (int cur:arr) {
        ero1^=(cur&rightestOne)==0?0:cur;
    }
    ero=ero^ero1;
    System.out.println("出现奇数次的数字分别是:"+ero+" "+ero1);
}

4.找出唯一出现K次的数字

题意:一个数组中有一种数出现K次,其他数都出现了M次,已知M > 1,K < M,找到出现了K次的数,要求额外空间复杂度O(1),时间复杂度O(N)

解题思路:

在这里插入图片描述

  • 说明:1.辅助数组为定长数组长度,空间复杂度为O(1)2.判断最右侧是不是(num>>i)&1,结果为1/0;提取最右侧的1:num&(-num),结果为2的整数次幂
  • 使用辅助数组统计本数组中有多少个数字第i个二进制位上为1——统计方法:得到每个元素的2进制序列,将1出现的情况加到统计数组中
  • 使用ans变量,遍历这个数组如果这个位置1出现的次数对m取模若为k,说明目标数字这一位上有这个1,把它搞进结果变量中——或的手段
  • 取模m可取的前提是k<m。否则可能存在km的存在倍数关系。

对数器:

  • 使用map的方式

  • 查找次数为k的数值遍历表的方法——keySet(key)或者entrySet(ky和value的关系)

    对数器使用的keySet,这里对entrySet的使用做演示:

Set<Map.Entry<String, String>> entryseSet=map.entrySet();
 
for (Map.Entry<String, String> entry:entryseSet) {
 
    System.out.println(entry.getKey()+","+entry.getValue());
 
}
//即通过getKey()得到K,getValue得到V
  • 打乱顺序(shuffleOrder):i位置数和随机生成的j(0~N-1)位置数进行交换

核心代码:

public static int km(int[] arr,int k,int m){
    int[] help=new int[32];
    //统计
    for (int cur:arr) {
        for (int i = 0; i < 32; i++) {
            help[i]+=(cur>>i)&1;
        }
    }
    //判断出现k次数的数中1出现的位置,并将相关状况放在ans的二进制序列中
    int ans=0;
    for (int i = 0; i < 32; i++) {
        ans|=help[i]%m==0?0:1<<i;
    }
    return ans;
}

测试代码:

    //for test
    public static int test(int[] arr,int k,int m){
        HashMap<Integer,Integer> map=new HashMap<>();
        for (int i = 0; i < arr.length; i++) {
            if(map.containsKey(arr[i])){
                map.put(arr[i],map.get(arr[i])+1);
            }else{
                map.put(arr[i],1);
            }
        }
        int ans=0;
        for (int num:map.keySet()) {
            if(map.get(num)==k){
                ans=num;
                break;
            }
        }
        return ans;
    }

    //for test
    public static int[] generateRandomArray(int maxKinds,int range,int k,int m){
        int kNum=(int) (Math.random()*(range+1))-(int) (Math.random()*(range+1));
        int kinds= (int) (Math.random()*maxKinds)+2;//2~maxkinds+1

        //System.out.println("kinds:"+kinds);
        int[] arr=new int[k+(kinds-1)*m];
        //生成km的随机函数没写对....
//        int[] arr= new int[0];
//        try {
//            arr = new int[k+(kinds-1)*m];
//        } catch (NegativeArraySizeException e) {
//            System.out.println("k:"+k);
//            System.out.println("kinds:"+kinds);
//            System.out.println("m:"+m);
            k:2
            kinds:0
            m:4
//            throw new RuntimeException(e);
//        }
        int index=0;
        for(;index<k;index++){
            arr[index]=kNum;
        }
        kinds--;

        HashSet<Integer> set=new HashSet<>();
        set.add(kNum);

        while(kinds--!=0){
            int curNum=0;
            do {
                curNum=(int) (Math.random()*(range+1))-(int) (Math.random()*(range+1));
            }while(set.contains(curNum));
            set.add(curNum);
            for (int i = 0; i < m; i++) {
                arr[index++]=curNum;
            }
        }
        shuffleOrder(arr);
        return arr;
    }

    //for test
    //打乱数组顺序:
    public static void shuffleOrder(int[] arr){
        for (int i = 0; i < arr.length; i++) {
            int j= (int) (Math.random()*arr.length);
            int tmp=arr[i];
            arr[i]=arr[j];
            arr[j]=tmp;
        }
    }

    //for test
    public static void main(String[] args) {
        boolean succeed=true;
        int kinds=5;
        int range=30;
        int maxTimes=9;
        int testTimes=1000;
        for (int i = 0; i < testTimes; i++) {

            int a = (int) (Math.random() * maxTimes) + 1; // a 1 ~ 9
            int b = (int) (Math.random() * maxTimes) + 1; // b 1 ~ 9
            int k = Math.min(a, b);
            int m = Math.max(a, b);
            // k < m
            if (k == m) {
                m++;
            }

            int[] arr=generateRandomArray(kinds,range,k,m);
            int ret1=km(arr,k,m);
            int ret2=test(arr,k,m);
            if(ret1!=ret2){
                System.out.println("k="+k+"  m="+m);
                System.out.println("km:"+ret1);
                System.out.println("test:"+ret2);
                System.out.println(Arrays.toString(arr));
                System.out.println("Oops!Error!");
                succeed=false;
                break;
            }
        }
        if(succeed){
            System.out.println("succeed!");
        }
    }

测试结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-anDCEMKM-1685088032677)(F:\typora插图\image-20230526153038004.png)]

位运算之异或运算题目总结

定义:

相同为0,相异为1。

理解:无进位相加

性质:

  • 0^N=N
  • N^N=0
  • 满足交换律和结合律

例题总结:

  • 不使用临时变量交换:三个等式aba
  • 寻找偶数次中的唯一奇数次:全部异或
  • 寻找偶数次中的唯二奇数次:异或分组异或;分组规则最右侧的1(相反数的补)
  • 寻找M次中的K次:辅助数组;对每个二进制统计(移位);对辅助数组遍历(或)

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

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

相关文章

这才是网络安全最系统的学习路线(建议收藏)

01 什么是网络安全 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“安全运维”则研究防御技术。 无论网络、Web、移动、桌面、云等哪个领域&#xff0c;都有攻与防两面…

一些小的问题

是否是质数&#xff1f; #include <stdio.h> #include <stdbool.h>bool is_prime(int num);int main() {int num;printf("请输入一个整数&#xff1a;");scanf("%d", &num);if (is_prime(num)) {printf("%d是质数。\n", num);} …

【萌新指南】如何获得铁粉?快收下我为你精心定制的涨粉秘籍吧

文章目录 前言"铁粉"介绍"铁粉"规则"铁粉"获取高质量博客坚持写博客参与活动 尾声 前言 目前博主的"铁粉"数量 "铁粉"介绍 "铁粉"是为了帮助博主解决上面提到的问题和困惑&#xff0c; CSDN 设计的一个功能&…

STM8、STM8S003F3P6 通过ZM470SX-MP模组实现lora通信

背景 现在物联网就是很火&#xff0c;lora是避免不开的&#xff0c;也有个项目采用STM8S003F3P6 使用周立功的lora模组ZM470SX-MP实现lora通信。 原理图 废话少说&#xff0c;上原理图 这个原理图我找了很久都没有找到&#xff0c;指示找到了管脚图&#xff0c;这个原理图非…

Linux——线程的同步与互斥

目录 模拟抢火车票的过程 代码示例 thread.cc Thread.hpp 运行结果 分析原因 tickets减到-2的本质 解决抢票出错的方案 临界资源的概念 原子性的概念 加锁 定义 初始化 销毁 代码形式如下 代码示例1&#xff1a; 代码示例2&#xff1a; 总结 如何看待锁 申…

2.自然语言处理NLP:词映射为向量——词嵌入(word embedding)

1. 什么是词嵌入&#xff08;word2vec&#xff09; &#xff1a; 把词映射为向量&#xff08;实数域&#xff09;的技术 2. 为什么不采用one-hot向量&#xff1a; one-hot词向量无法准确表达不同词之间的相似度&#xff0c;eg&#xff1a;余弦相似度&#xff0c;表示夹角之间的…

创新案例|Amazon如何打造增长飞轮保持每年20%以上的营收增速

作为世界五百强中的头部企业&#xff0c;亚马逊的价值定位经历了三次转变&#xff0c;从成为“地球上最大的书店”&#xff0c;到成为最大的综合网络零售商&#xff0c;再到成为“最以客户为中心的企业”&#xff0c;亚马逊最终以“客户中心”破除了对企业价值定位的束缚&#…

DNS风险分析及安全防护研究(三):DNS缓存投毒及防御策略

在前面章节中&#xff0c;我们简单介绍了DNS系统在协议、软件以及结构中脆弱性&#xff0c;并对DNSSEC协议、去中心化结构等安全增强进行了讨论&#xff0c;接下来针对DNS安全所面临的外部攻击威胁和相应的防御策略做下讨论。 1.DNS缓存投毒攻击 在目前各种DNS攻击手段中&…

安科瑞浅谈集成式电力电容器无功补偿装置的技术特点

安科瑞 徐浩竣 江苏安科瑞电器制造有限公司 zx acrelxhj 摘要&#xff1a;阐述了集成式电力电容器无功补偿装置的组成与应用状况&#xff0e;在与常规电力电容器对比的基础上&#xff0c;分析了集成式电力电容器无功补偿装置的技术特点。通过对集成式无功补偿装置原理结构的…

Linux文件系统、磁盘I/O是怎么工作的?

同CPU、内存一样&#xff0c;文件系统和磁盘I/O&#xff0c;也是Linux操作系统最核心的功能。磁盘为系统提供了最基本的持久化存储。文件系统则在磁盘基础上&#xff0c;提供了一个用来管理文件的树状结构。 目录&#xff1a; 一. 文件系统 1. 索引节点和目录项 2. 虚拟文件系…

提升国际品牌影响力:小企业海外网红营销实战指南

在当今数字化时代&#xff0c;小企业们越来越意识到海外市场的巨大潜力。与此同时&#xff0c;海外网红的崛起也为小企业提供了一个独特的机会&#xff0c;通过与他们合作&#xff0c;迅速拓展国际市场并吸引更多目标受众的关注。然而&#xff0c;对于许多小企业来说&#xff0…

超全性能测试-全链路压测总结,完整一套从环境到脚本详细...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 性能测试&#xf…

类和对象 --- 封装+对象特性

&#x1f442; 快乐E调 - 林澜叶 - 单曲 - 网易云音乐 &#x1f442; Plain Jane (Freestyle) - Ombre2Choc Nation - 单曲 - 网易云音乐 1.5倍速&#xff0c;跟着敲&#xff0c;初识C 目录 &#x1f3c6;封装 &#x1f333;属性和行为作为整体 &#x1f333;案例 -- 设置…

js数组去重与循环对象

目录 一、数组对象去重 1.1、需要获取重复数据 1.2、直接过滤filterfindIndex 二、循环对象 三、多层数组对象过滤 一、数组对象去重 1.1、需要获取重复数据 let persons [{"name": "yzq","age": 20,"gender": true,"hei…

k8s配置资源管理|secret|configmap

k8s配置资源管理|secret|configmap 一 配置资源管理1 创建 Secret2 使用方式3 将 Secret 导出到环境变量中 二 ConfigMap1 Pod 中使用 ConfigMap2 Pod的创建3 用 ConfigMap 设置命令行参数4 通过数据卷插件使用ConfigMap 一 配置资源管理 //Secret Secret 是用来保存密码、tok…

2023年6月合肥/厦门/长春/深圳DAMA-CDGP数据治理专家认证报名

目前6月18日CDGA&CDGP考试目前开放的城市有&#xff1a;北京、上海、广州(满)、深圳、长沙、呼和浩特、杭州&#xff08;满&#xff09;、南京、济南&#xff08;满&#xff09;、成都、西安、武汉&#xff08;满&#xff09;、天津。 新增了武汉、天津这2个城市。另外合肥…

【Netty】Reactor 模型(十)

文章目录 前言一、传统服务的设计模型二、NIO 分发模型三、Reactor 模型3.1、Reactor 处理请求的流程3.2、Reactor 三种角色 四、单Reactor 单线程模型4.1、消息处理流程4.2、缺点 五、单Reactor 多线程模型5.1、消息处理流程5.2、缺点 六、主从Reactor 多线程模型6.1、Reactor…

Python的一些基础实操练习题

书接上文多看一眼多进步&#xff0c;python入门到放弃&#xff0c;是根据python的知识点的一些基础练习题&#xff0c;说了是基础练习题&#xff0c;基础练习题&#xff0c;基础练习题&#xff0c;水平高的就别看了&#xff0c;平高的就别看了&#xff0c;高的就别看了&#xf…

IP协议-服务类型字段

服务类型&#xff08;Type of Service&#xff09;字段是比较复杂的一个字段&#xff0c;该字段经过多次标准变更。 IPv4报文 一、最初标准&#xff08;RFC 791&#xff09; RFC 791定义TOS字段总共占用8bit&#xff0c;分为IP Precedence优先级&#xff08;3bit&#xff09;、…

Ansys Zemax | 如何将高斯光整形为平顶光

概要 本文展示了如何设计光束整形器将激光器产生的高斯分布的光转换为平顶分布的光输出。&#xff08;联系我们获取文章附件&#xff09; 介绍 光束整形光学元件可以将入射光的光强分布转换为其他特定的分布输出。最常见的例子就是将激光器产生的高斯分布的光转换为平顶&#x…