• 编程之美 快速找出机器故障问题


    题目:

      简化后问题:有很多机器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

  • 相关阅读:
    201771030123-王爽 实验一 软件工程准备—阅读《现代软件工程—构建之法》并提问
    《面向对象程序设计课程学习进度条》
    201771010132-徐思 实验四 软件项目案例分析
    201771010132-徐思 实验三 结对项目-《西北师范大学疫情防控信息系统》
    201771010132-徐思 实验一 软件工程准备-浏览《构建之法》
    徐思201771010132 《面向对象程序设计(java)》课程学习总结
    徐思 201771010132
    徐思201771010132《面向对象程序设计(java)》第十六周学习总结
    徐思201771010132《面向对象程序设计(java)》第十五周学习总结
    徐思201771010132《面向对象程序设计(java)》第十四周学习总结
  • 原文地址:https://www.cnblogs.com/edward-tj/p/4504056.html
Copyright © 2020-2023  润新知