快速找出故障机器

《编程珠玑》1.5节:快速找出故障机器

主要是能够在一组数组中找出丢失的数。

1、在数组A中,除了一个数只出现一次外,其他数都出现两次。用异或来解,最后得到的数就是丢失的数。

#include<iostream>
using namespace std;

int findLost(int A[],int N)
{
	int result=0;
	for(int i=0;i<N;i++)
		result^=A[i];
	return result;
}

int main()  
{  
	const int N=9;
	int A[N]={1,2,3,4,1,2,3,4,8};
	cout<<findLost(A,N)<<endl;

    system("pause");  
    return 0;  
}
2、在数组A中,除了两个数只出现一次外,其他数都出现两次。用两次异或来解。第一次异或找出的是两个丢失的数的异或,此时根据异或结果,可以找出两个数的不同的位,比如第bit位,那么进行第二次异或时,bit位为1的值和num1进行异或,bit位为0的值和num2进行异或,最后可以得到两个数。

#include<iostream>
#include<algorithm>
using namespace std;

pair<int,int> findLostTow(int A[],int N)
{
	int num1=0,num2=0;
	for(int i=0;i<N;i++)
		num1^=A[i];
	int bit=0;
	for(int i=0;i<32;i++)
	{
		if(num1 & (1<<i))
		{
			bit=i;
			break;
		}
	}
	num1=0;
	for(int i=0;i<N;i++)
	{
		if(A[i]&(1<<bit)==1)
			num1^=A[i];
		else
			num2^=A[i];
	}
	return pair<int,int>(num1,num2);
}

int main()  
{  
	const int N=10;
	int A[N]={1,2,3,4,1,2,3,4,8,7};
	pair<int,int> p=findLostTow(A,N);
	cout<<p.first<<"	"<<p.second<<endl;

    system("pause");  
    return 0;  
}
3、如果数组中丢失数之前已经知道数组和,即这些先验是已知的,那么就可以用其和,平方和,或者乘积等对丢失数据进行计算,然后列方程求解。例如求数组中丢失的两个数时,用二元二次方程求解:

#include<iostream>
#include<algorithm>
using namespace std;

pair<int,int> findLostTow(int A[],int N,int sum,int powSum)
{
	int s=0,pows=0;
	for(int i=0;i<N;i++)
	{
		s+=A[i];
		pows+=A[i]*A[i];
	}
	int num1=0,num2=0;
	int add=sum-s,minus=int(sqrt(double(2*powSum-2*pows-sum*sum-s*s+2*s*sum)));
	return pair<int,int>((add+minus)>>1,(add-minus)>>1);
}

int main()  
{  
	const int N=10;
	int A[N]={1,2,3,4,1,2,3,4,8,7};
	pair<int,int> p=findLostTow(A,N,50,286);
	cout<<p.first<<"	"<<p.second<<endl;

    system("pause");  
    return 0;  
}
4、如果要求的未知数增多,只需要增加方程即可,但是随着未知数个数增多,复杂度也会上升。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值