通过异或运算 找出唯一成对的数

这篇博客介绍了一种Java实现的方法,通过按位异或操作找到数组中唯一重复的数字。程序首先填充了一个长度为1001的数组,并在末尾随机插入一个1到1000之间的数,然后通过随机索引交换,使得数组只有一个重复的元素。之后,利用按位异或的性质找出这个重复的数字。此外,还提供了一种通过计数法寻找重复元素的备用方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述
package test;

import java.util.Random;

public class WeiYunSuan {
public static void main(String[] args) {
int N=1001;
int arr[]=new int[N];
Random random=new Random();
for(int i=0;i<arr.length-1;i++){
arr[i]=i+1; //填充数组arr[0]-arr[1000]
}
arr[arr.length-1]=random.nextInt(N-1)+1; //arr[1001] 随机生成1000内的数
int index=random.nextInt(N); //随机生成索引
swap(arr,index, arr.length-1);
//将arr[1001]与arr[index] 交换值,那么arr[0]-arr[1000] 就有唯一重复的元素了

/* 利用按位异或解题
A^A=0
A^0=A
所以 ( arr[0]^arr[1] ^arr[2] ^…k ^ k.arr[arr.length-1] ) ^ (1 ^2 ^3… ^k… ^1000)
=arr[0] ^1 ^arr[1] ^2…k ^ k ^ k … ^arr[1000] ^1000 (arr[0]与1值相同,所有成对的按位异或后都为0 )
=k

*/

    int x=0;
    for (int i = 1; i <=arr.length-1; i++) {						
        x=x^i;														(0 ^1 ^2.... ^1000) 按位与完结果为x
    }
    for (int i = 0; i < arr.length; i++) {
        x=x^arr[i];										再接着 x ^ arr[0] ^arr[1] ^arr[2] ^arr[3]...^arr[1000]
    }
     print(arr);										//输出唯一重复的元素
    System.out.println("x:"+x);
    System.out.println("------方法2--------");		//该方法开辟存储空间,做对比用

/* 因为arr[i]里只有一个重复的值,所以就可以将arr[i]的值作为brr[i]的索引,若出现一次arr[i]的值 , brr[arr[i]]值就+1 因为arr[i]只有一个元素重复,所以brr[i]==2的情况只存在一种,输出brr[i]的索引i,也就是输出arr中重复的值
*/
在这里插入图片描述

    int brr[]=new int[N];					
    for (int i = 0; i < brr.length-1; i++) {											 
        brr[arr[i]]++;
    }
    for (int i = 0; i < brr.length-1; i++) {
        if (brr[i] == 2) {
            System.out.println("i:" + i);
            break;
        }
    }
}
//i 和 j交换值			 ,用于生成的随机数和数组中的任意一个位置交换值,使得arr数组只有唯一一个值重复
public static void swap(int arr[],int i,int j){
    int t;
    t=arr[i];
    arr[i]=arr[j];
    arr[j]=t;
}
public static void print(int arr[]){
    for (int i : arr) {								//输出数组arr 的值
        System.out.print(i+" ");
    }
    System.out.println();
}

}

运行结果如下:
在这里插入图片描述

### C语言中异或运算的使用方法和示例 #### 一、基本概念 C语言中的异或运算是通过 `^` 符号来完成的一种位操作。它会对两个整的每一位进行比较,只有当两位不同(一位为0另一位为1)时,结果才为1;否则结果为0[^1]。 #### 二、实现原理 对于任意两个整a和b,在执行 `result = a ^ b` 后,其对应的二进制形式会逐位按照上述规则计算得出最终的结果。例如: ```c int a = 5; // 二进制:0101 int b = 3; // 二进制:0011 int result = a ^ b; // result 的二进制:0110,即十进制6 ``` 此过程展示了如何利用异或运算处理简单的值转换[^2]。 #### 三、实际应用案例分析 ##### 加法器设计 可以借助按位异或特性构建无需传统算术指令即可工作的加法功能模块。以下是具体代码片段展示这一思路的应用场景之一——两相加而不用"+"符号: ```c #include <stdio.h> int add(int x, int y){ while(y != 0){ int carry = (unsigned)(x & y) << 1; x = x ^ y; y = carry; } return x; } int main(){ printf("%d\n",add(-2,3)); //-2+3=1 } ``` 这里运用到了循环结构不断更新被加与进位直到没有新的进位产生为止[^3]。 ##### 缺失字查找算法 另一个典型例子是在给定组里寻找唯一未重复项或者发现序列中存在的缺失值等问题上也经常采用这种方法。比如下面这段程序就是用来找出从零到某个最大自然之间缺少的那个特定成员的方法论体现: ```c int missingNumber(int* nums, int numsSize){ int target=0;//初始化变量target初值设为0因为任何同0做XOR都等于自身 for(int i=0;i<numsSize;i++){ target ^=i; //先将索引位置上的连续整值累积起来 target ^=nums[i]; //再把当前遍历过的每一个元素逐一加入其中抵消掉已存在的配对项目 } target ^=numsSize; //最后还需额外补充最后一个可能遗漏的最大边界条件n本身才行哦~ return target; } ``` 这种技巧依赖于这样一个事实:相同的一对儿正负相反经过一次完整的异或之后就会相互抵销归零[^4]。 #### 四、注意事项 需要注意的是不同类型长度的据参与此类位级运算可能会引发一些意想不到的行为模式因此建议开发者们务必清楚知晓所涉及据类型的存储规格以及相应机器架构下默认填充方式等方面的知识点以便更好地控制整个流程走向达到预期效果[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值