题目:
简化后问题:有很多机器id,其中只有一个或两个id被丢失,正常情况下每个id个数为2,请问如何找到丢失的id是几。
java解法一实现:
/**
* 使用异或操作 X异或X等于0,X异或0等于X,所有元素异或结果就是丢失的元素
* 如果丢失id个数为2,异或结果就是A异或B的结果,然后将数组分成两组,分别找出来。
* @author zhaozh
*
*/
public class MachineErrorID1 {
private int[] machineIds;//所有机器id列表
private int[] deleteIdIndexes;//丢失的机器id列表索引
private int[] lostIds;//丢失的机器id
public MachineErrorID1(int[] machineIds, int[] deleteIdIndexes){
this.machineIds = new int[machineIds.length - deleteIdIndexes.length];
int k = 0;
for(int i = 0; i < machineIds.length; i++){//初始化丢失id后的机器id列表
boolean flag = true;
for (int j = 0; j < deleteIdIndexes.length; j++){
if(i == deleteIdIndexes[j])
flag = false;//被删除
}
if(flag){
this.machineIds[k++] = machineIds[i];
}
}
this.deleteIdIndexes = deleteIdIndexes;
this.lostIds = new int[deleteIdIndexes.length];
}
public void findLostmachineIds(){
if(deleteIdIndexes.length == 1){
lostIds[0] = findLostMachineId();
}else{
int i_result = findLostMachineId();
lostIds = findLostMachineId(i_result);
}
}
private int[] findLostMachineId(int i_result){
if(i_result == 0){
System.out.println("被删除的两个id是一样的,我找不出来了。");
return null;
}else{
int i_temp = 1;
while((i_result & i_temp) == 0)
i_temp = i_temp << 2;
int[] i_lostIds = new int[2];
for(int i = 0; i < machineIds.length; i++){
if((i_temp & machineIds[i]) == 0){
i_lostIds[0] = i_lostIds[0] ^ machineIds[i];
}else if((i_temp & machineIds[i]) != 0){
i_lostIds[1] = i_lostIds[1] ^ machineIds[i];
}
}
return i_lostIds;
}
}
private int findLostMachineId(){
int i_lostId = 0;
for (int i = 0; i < machineIds.length; i++) {
i_lostId = i_lostId ^ machineIds[i];
}
return i_lostId;
}
public void output(){
if(lostIds != null){
System.out.println("the lost machine id is :" );
for(int i = 0; i < lostIds.length; i++){
System.out.print(" " + lostIds[i]);
}
}
}
public static void main(String[] args) {
int[] machineIds = new int[]{1,1,2,2,3,3,4,4,5,5};
int[] deleteIdIndexes = new int[]{1,9};
MachineErrorID1 machineErrorId = new MachineErrorID1(machineIds, deleteIdIndexes);
machineErrorId.findLostmachineIds();
machineErrorId.output();
}
}
java解法二实现:
/**
* 原理:末丢失id前的id总和,减去丢失id后的总和,就是丢失的id。
* 如果丢失一下,就可以直接找出来
* 如果丢失的是两个,就要再构造一个方程,如丢失前后,所有id的乘积之差(防止溢出也可以是 所有id的平方和)。由x+y=a,x*y=b求出x,y
* @author zhaozh
*
*/
public class MachineErrorID2 {
private int[] machineIds;//所有机器id列表
private int[] deleteIdIndexes;//丢失的机器id列表索引
private int[] lostIds;//丢失的机器id
private int sum_ids;//丢失前id的和
private int mult_ids;//丢失前id的积
public MachineErrorID2(int[] machineIds, int[] deleteIdIndexes){
this.machineIds = new int[machineIds.length - deleteIdIndexes.length];
int k = 0;
for(int i = 0; i < machineIds.length; i++){//初始化丢失id后的机器id列表
boolean flag = true;
for (int j = 0; j < deleteIdIndexes.length; j++){
if(i == deleteIdIndexes[j])
flag = false;//被删除
}
if(flag){
this.machineIds[k++] = machineIds[i];
}
}
for(int i = 0; i < machineIds.length; i++){//计算id的和
sum_ids += machineIds[i];
}
if(deleteIdIndexes.length > 1){//计算id的积
mult_ids = machineIds[0];
for(int i = 1; i < machineIds.length; i++){
mult_ids *= machineIds[i];
}
}
this.deleteIdIndexes = deleteIdIndexes;
this.lostIds = new int[deleteIdIndexes.length];
}
public void findLostmachineIds(){
if(deleteIdIndexes.length == 1){
lostIds[0] = sumMachineId();
}else{
int i_multi = multiMachineId();
int i_sum = sumMachineId();
lostIds[1] = (int) ((i_sum + Math.sqrt(i_sum * i_sum - 4 * i_multi))/2);
lostIds[0] = i_sum - lostIds[1];
}
}
private int multiMachineId(){
int i_multids = machineIds[0];
for(int i = 1; i < machineIds.length; i++){
i_multids *= machineIds[i];
}
return this.mult_ids / i_multids;
}
private int sumMachineId(){
int i_lostId = 0;
for (int i = 0; i < machineIds.length; i++) {
i_lostId += machineIds[i];
}
return this.sum_ids - i_lostId;
}
public void output(){
if(lostIds != null){
System.out.println("the lost machine id is :" );
for(int i = 0; i < lostIds.length; i++){
System.out.print(" " + lostIds[i]);
}
}
}
public static void main(String[] args) {
int[] machineIds = new int[]{1,1,2,2,3,3,4,4,5,5};
int[] deleteIdIndexes = new int[]{1,9};
MachineErrorID2 machineErrorId = new MachineErrorID2(machineIds, deleteIdIndexes);
machineErrorId.findLostmachineIds();
machineErrorId.output();
}
}
输出结果:
the lost machine id is :
1 5