题目来自编程之美
题目 1:假设一个机器只存储一个标号为ID的记录,假设每份数据保存2个备份,这样就有2个机器存储了相同的数据。其中ID是小于10亿的整数,在某个时间,如果得到一个数据文件ID的列表。是否能够快速的找到这个表中仅出现一次的ID?即快速找出出现故障的机器存储的数据ID。
分析:具体参考点击打开链接
代码
#include <iostream>
#include <assert.h>
using namespace std;
/*函数nArr中的只有一个元素出现一次,其他元素都是出现两次*/
int Find(int nArr[],int nLen)
{
assert(nArr != NULL && nLen > 0 && nLen % 2 == 1);
int nNum = 0;
for (int i = 0;i < nLen;i++)
{
nNum ^= nArr[i];
}
return nNum;
}
int main()
{
int nArr[9];
for (int i = 0;i < 9;i++)
{
cin>>nArr[i];
}
cout<<Find(nArr,9)<<endl;
system("pause");
return 1;
题目 2:
假设一个机器只存储一个标号为
ID
的记录,假设每份数据保存
2
个备份,这样就有
2
个机器存储了相同的数据。其中ID是小于10亿的整数,如果有两台机器死机呢?(假设同一个数据的俩个备份不会同时丢失,即列表中缺少的是两个不等的ID)
分析:具体参考点击打开链接
代码:
#include <iostream>
#include <assert.h>
using namespace std;
int FindLastOne(int nNum)
{
assert(nNum > 0);
int nPos = 1;
int nLast = nNum & 1;
while (0 == nLast)
{
nPos++;
nNum >>= 1;
nLast = nNum & 1;
}
return nPos;
}
/*判断nNum的nPos位置上是否为1*/
bool IsSameBit(int nNum,int nPos)
{
assert(nPos >= 0);
return nNum & (1 << (nPos - 1)) ? true : false;
}
/*函数nArr中有两个元素都出现一次,其他元素都是出现两次*/
void Find(int nArr[],int nLen)
{
assert(nArr != NULL && nLen > 0);
int nNum = 0;
int nPos = 0;
int nNumFirst = 0;
int nNumSec = 0;
//首先把所有元素都异或一遍
for (int i = 0;i < nLen;i++)
{
nNum ^= nArr[i];
}
/*根据最后异或的结果中1的位置,把数据分两组,并分别在每组进行异或*/
nPos = FindLastOne(nNum);
for (int i = 0;i < nLen;i++)
{
if (IsSameBit(nArr[i],nPos)) //nArr[i]在nPos位置为1
{
nNumFirst ^= nArr[i];
}
else //nArr[i]在nPos位置为0
{
nNumSec ^= nArr[i];
}
}
cout<<"Losing Num: "<<nNumFirst<<" "<<nNumSec<<endl;
}
int main()
{
int nArr[8] = {1,2,3,1,2,4,5,4};
Find(nArr,8);
system("pause");
return 1;
}