快速找出两个列表差异部分

int [] arr0 = new int [] {1 ,5 ,12 ,21 ,11 ,15 ,8 ,30} ;
 int [] arr2 = new int [] {2 ,3 ,12 ,9 ,17 ,30 ,25 ,35} ;
 
 // 将两个列表排序(升序)
 Arrays.sort(arr0);
 Arrays.sort(arr2);
 
 // log.info("==>{}" ,arr0); // [1, 5, 8, 11, 12, 15, 21, 30]
 // log.info("==>{}" ,arr2); // [2, 3, 9, 12, 17, 25, 30, 35]

 // 下面的比较算法只适用于两个列表长度相同时,否则应改进之 
 for(int i = 0 ,j = 0 ; i < arr0.length && j < arr2.length ;) {
     if(arr0[i] > arr2[j]) {
         log.info("A没有B有\t+>:{}" ,arr2[j]);
         j++ ;
     } else if(arr0[i] < arr2[j]) {
         log.info("A有B没有\t->:{}" ,arr0[i]);
         i++ ;
     } else {
        log.info("AB都有\t=>:{}" ,arr0[i]);
        i ++ ;
        j ++ ;
     }
 } 

 

下面给出一个改进型的算法,用于解决两个列表不能同时遍历完全的情况:

// 两个比较列表
		int [] arri = new int [] {1 ,5 ,12 ,21 ,11 ,72 ,15 ,8 ,30 ,17 ,43 ,21 ,56} ;
		int [] arrj = new int [] {2 ,3 ,12 ,9 ,17 ,30 ,25 ,35 ,21 ,41 ,58 ,72} ;
		
		// 将两个列表排序(升序)
		Arrays.sort(arri);
		Arrays.sort(arrj);
		
		List<Integer> iList = new ArrayList<Integer>() ;	// i列表
		List<Integer> jList = new ArrayList<Integer>() ;	// j列表
		List<Integer> eqList = new ArrayList<Integer>() ;	// eq列表
		
		// 下面的比较算法只适用于两个列表长度相同时,否则应改进之
		int i = 0 ,j = 0 ;
		for(; i < arri.length && j < arrj.length ;) {
			if(i > 0 && arri[i - 1] == arri[i]) i++ ;		// 如果当前i与上一元素相等,跳过,避免单个列表重复元素在另外一个列表中至少也存在一个时,会错误两个同时递增导致非预期结果
			if(j > 0 && arri[j - 1] == arrj[j]) j++ ;		// 如果当前j与上一元素相等,跳过
		    if(arri[i] > arrj[j]) {
		        jList.add(arrj[j]) ;
		        j++ ;
		    } else if(arri[i] < arrj[j]) {
		        iList.add(arri[i]) ;
		        i++ ;
		    } else {
		       eqList.add(arri[i]) ;
		       i ++ ;
		       j ++ ;
		    }
		}
		
		// 上面循环结束条件是i、j有一个遍历完全,所以只有三种情况
		if(i == arri.length && j < arrj.length) {
			System.out.println("j 未完成遍历!");
			// i与长度相等,说明i已遍历完全,但j小于长度,说明还有剩下的没有遍历到,原因是剩下的都比i最后一个元素要大(默认两个列表都按从小到大排序)
			for(int m = j ,len = arrj.length ; m < len ; m ++) {
				jList.add(arrj[m]) ;
			}
		} else if(i < arri.length && j == arrj.length) {
			System.out.println("i 未完成遍历!");
			// j与长度相等,说明j已遍历完全,但i小于长度
			for(int n = i ,len = arri.length ; n < len ; n ++) {
				iList.add(arri[n]) ;
			}
		} else {
			System.out.println("i、j皆完成遍历!");
			// i与长度相等、j与长度相等,即两个都遍历完全
			// 如果两个列表最大值相等,则一定会都遍历完全
		}
		
		System.out.println("i :" + iList.toString());	// i :[1, 5, 8, 11, 15, 43, 56]
		System.out.println("j :" + jList.toString());	// j :[2, 3, 9, 25, 35, 41, 58]
		System.out.println("eq:" + eqList.toString());	// eq:[12, 17, 21, 30, 72]

 

 

 

转载于:https://my.oschina.net/zhanglikun/blog/413747

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值