异或 二进制 全排列

本文介绍了异或运算在编程中的一些实用技巧,包括如何使用异或快速交换两个数的值而不使用临时变量,提取二进制最右侧的1,找出一堆数中出现奇数次的两个数,以及计算一个数中二进制1的个数。通过这些实例,展示了异或在解决算法问题时的高效性和便捷性。
摘要由CSDN通过智能技术生成

使用异或快速交换两个数的值,不用写临时变量

原理是异或可以找出奇数次出现的数
import java.util.Scanner;

public class Text {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int a=51;
        int b=33;
        a=a^b;
//        此时a=a^b,b=b
        b=a^b;
//        此时b=a^b^b 结果为a
        a=a^b;
//        此时a=a^b^a 结果为b
    }
}

在这里插入图片描述

提取一个数二进制最右侧的1

n&((~n)+1)

取反加一再进行同原数进行与操作

import java.util.Scanner;

public class Text {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int a = 7;
//        7=111,最右侧1为1
        System.out.println(~a);
        System.out.println(~a+1);
        System.out.println(a & (~a+1));
    }
}

在这里插入图片描述

在一大堆数中有两个不同数出现了奇数次,别的数都是偶数次,提取出这两个数

异或偶数次时,结果为0 1异或1=0 ,1 异或1异或1=1
异或所有数,得到结果res,最终会得到两个数异或的结果,偶数次的数不造成影响,然后提取出最右边的1,flag,要找的两个数必不一样,肯定会有不一样的一位。把一大堆数按flag分成两类,要找的两个数也会被分在这两类中,即,一个数在flag为 1类中,另一个数在flag=0类中,再用之前res进行分类异或,得到要寻找的第一个数a,a异或res,得b

import java.util.Scanner;

public class Text {
    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        int a = 0, b = 0;
        int y[] = {1, 1, 5, 2, 2, 3};
        int res = 0;
        for (int i = 0; i < y.length; i++) {
            res = res ^ y[i];
        }
        int flag = res & (~res + 1);
        int c=0;
        for (int i = 0; i < y.length; i++) {
            if ((flag&y[i])==0) {
                a = res ^ y[i];
            }
        }
        System.out.println(a);
        System.out.println(res^a);
    }
}

在这里插入图片描述

数一个数中有几个二进制一

取一个最右边1异或一次,直到a为0

import java.util.Scanner;

public class Text {
    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        int a=sc.nextInt();
        int c=0;
        int flag = 0;
        while (a!=0){
            flag = a & (~a + 1);
            c++;
            a^=flag;
        }
        System.out.println(c);
    }
}



在这里插入图片描述
在这里插入图片描述

全排列

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Scanner;

public class Text {
    public static void all(String s[],HashSet<Integer> used,
                           String y,ArrayList<String> list){
        if (used.size()==s.length)
           list.add(y);

        else {
            for (int i = 0; i <s.length ; i++) {
                if (!used.contains(i)){
                    used.add(i);
                    all(s,used,y+s[i],list);
                    used.remove(i);
                }
            }
        }
    }
    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        String s[]={"a","b","c"};
        String y = "";
        HashSet<Integer> used=new HashSet<>();
        ArrayList<String> list=new ArrayList<>();
        all(s,used,y,list);
        for (String s1:list
             ) {
            System.out.println(s1);

        }
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值