快速找出故障机器
关心数据挖掘和搜索引擎的程序员都知道,我们需要很多的计算机来存储和处理海量数据。然而,计算机难免出现硬件故障而导致网络联系失败或死机。为了保证搜索引擎的服务质量,我们需要保证每份数据都有多个备份。
简单期间,我们假设一个机器仅存储一个标号为ID的记录(假设ID是小于10亿的整数),假设每份数据保存两个备份,这样就有两个机器存储了同样的数据。
1、 在某个时间,如果得到一个数据文件ID的列表,是否能够快速找出这个表中仅出现一次的ID?
2、 如果已经知道只有一台机器死机呢?如果有两台机器死机呢?
好了说人话,有两个ID表,其中异常的ID只会在其中一个表中出现,正常是两个ID表中都有,问假如只有一个ID异常,怎么找出来?假如有两个ID异常怎么找出来?
解题思路:
1、 遍历是肯定可以解决的。
书上列举了四个方案?在这里就不一一讲解了,挑两个我觉得比较有意思的说说。
一个异常ID的例子
想想如果机器全部正常的话,ID异或值就是0啊,如果只有一台异常,少了一个和它配对的,那么剩余的ID异或值是不是就是这个异常的ID?
二个异常ID的例子
因为正常时候的列表我们是事先知道的,那么我们了以假设异常的ID为x,y。那就有
x+y = 正常和-异常和
x*y=正常乘积/异常积
代码示例:
// 寻找一个异常值
int findOneUnNormalId(int *IDlist1,int IDlist1Size,int *IDlist2, int IDlist2Size)
{
int id = 0;
for (int i = 0; i < IDlist1Size; ++i)
{
id ^= *(IDlist1 + i);
}
for (int j = 0; j < IDlist2Size; ++j)
{
id ^= *(IDlist2 + j);
}
return id;
}
// 寻找二个异常值
void findTwoUnNormalId(int *IDlist1, int IDlist1Size,
int *IDlist2,
int IDlist2Size,
long long sum,
long long product,
int x,
int y)
{
long long addsum = 0;
long long mux = 0;
for (int i = 0; i < IDlist1Size; ++i)
{
addsum += *(IDlist1 + i);
mux *= *(IDlist1 + i);
}
for (int j = 0; j < IDlist2Size; ++j)
{
addsum += *(IDlist1 + j);
mux *= *(IDlist1 + j);
}
int dvalue_add = sum - addsum;
int dvalue_mul = product / mux;
for (int i = 0; i < dvalue_add; ++i)
{
for (int j = 0; j < dvalue_add; ++j)
{
if ((i * j) == dvalue_mul && (i + j) == dvalue_add)
{
x = i;
y = j;
return;
}
}
}
}