題目:
簡化後問題:有很多機器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