【芯片测试】有n片芯片,已知好芯片比坏芯片至少多1片。现在需要通过测试从中找出1片好芯片,测试方法如下:将2片芯片放到测试台上,2片芯片互相测试并报告测试结果(即好或者坏);其中,好芯片的报告是正确的,而坏芯片的报告是不可靠的。为保证使用更少的测试次数,请设计一个合适的算法解决上述问题

算法设计思路

  1. 当芯片数为偶数时,每两个互相测试,测试保存下来的芯片存到一个数组中(该数组记录原数组的芯片的下标)。
  2. 当芯片为奇数的时候,将从第一个芯片开始不断与最后一个芯片互相测试,当测试到最后一个芯片的结果为好的次数大于或者等于芯片数量的一半,则说明其为好芯片,否则为坏芯片。若为坏芯片,则不用管它,相当于奇数减一变成偶数了,因为偶数时是两个两个这样遍历的,如果最后一个为坏芯片,是多出来的奇数,也不会遍历到它(假设有5枚芯片,从第一片和第二片互相测试,第三片和第四片互相测试,再当n+2就大于5等于6了,不合乎循环条件了,则就自然不会遍历到最后一个芯片)

测试原则:

将这个数组的对应原数组的下标再开始两两测试。1、若测试结果都为好,则选一片出来保存,2、若测试结果一好一坏,或者两个都是坏,则都舍,这样的方法能保证舍弃的坏芯片最终会大于等于好芯片。

测试保存下来的芯片再放回这个数组,每次从该数组的首部开始放入,覆盖掉上一组的数据,不断循环下去,直到剩余3片芯片或者1片、2片。因为好芯片总要比坏芯片多1,所以剩下3片的时候,随便拿两片出来就可以得到一片好芯片(假设拿两个好的,直接保留一块,如果拿一好一坏,则都舍弃,剩下的就是好的),剩下2片或者剩下1片的时候,肯定都是好的。

算法实现的伪代码

算法compare( boolean[ ] chipArr , int left,  int right)

输入:存放芯片的数组、左下标、右下标

输出:布尔值

  1. if (chipArr[left] = true && chipArr[right] = true)
  2. return true;
  3. else if ((chipArr[left] = true && chipArr[right] = false) || (chipArr[left] = false && chipArr[right] = true))
  4. return false;
  5. else
  6. if (r.nextInt(3) == 0)
  7. return true;
  8. else
  9. return false;

算法chipTest( boolean[ ] chipArr )

输入:存放芯片的数组、左下标、右下标

输出:布尔值

  1. count 当剩余芯片为奇数的时候用于记录对比结果为true的次数
  2. temp[chipArr.length] 用于记录筛选出来的芯片的下标
  3. Chip = chipArr.length 剩余芯片数
  4. for i = 0 to chipArr.length
  5. tempArr[ i ] = i
  6. while (Chip > 3)
  7. if (Chip % 2 != 0) 奇数
  8. compareChip = Chip-1 最后一枚芯片下标
  9. 将其他芯片与最后一片芯片互相测试
  10. if count 大于或等于芯片的数量的一半
  11. then 这个是好芯片,直接输出
  12. n = Chip 保留芯片的数量
  13. Chi = 0
  14. for i= 1 to n i+=2
  15. 后一片芯片与前一片芯片互相测试,
  16. if 保留到芯片
  17. then Chip++、
  18. if Chip = 3
  19. then 直接判断得出好芯片

实现代码

import java.util.Random;public class Main {static Random r = new Random();public static void main(String[] args) {boolean[] chipArr = {false,false,true,false,true,true,true,true,false};//初始化数组chipTest(chipArr);}public static void chipTest(boolean[] chipArr) {int count = 0;      //当剩余芯片为奇数的时候用于记录对比结果为true的次数,若count >= 芯片数的一半,则说明被检测的那个芯片(选取最后一个)是好芯片,否则坏芯片int[] tempArr = new int[chipArr.length];     //用于记录筛选出来的芯片的下标int Chip = chipArr.length;      //剩余芯片数for (int i = 0; i < chipArr.length; i++) {tempArr[i] = i;     //为记录数组初始化,值对应这chipArr的下标}while (Chip > 3) {      //当剩余芯片数大于3的时候就一直比较if (Chip % 2 != 0) {        //剩余芯片数为奇数时,用暴力算法,比较最后一枚芯片和其他芯片int compareChip = Chip-1;       //最后一枚芯片的下标for (int i = 0; i < compareChip; i++) {     //从第一枚芯片开始到最后一枚的前一枚与最后一枚芯片比较if(compare(chipArr,compareChip,i))count++;        //若返回为true,则count++if(count >= (Chip-1)/2){        //若刚刚好最后一个为好芯片,则直接输出,结束循环System.out.println(tempArr[i]);break;}else count = 0;}if(count >= (Chip-1)/2)break;}int n = Chip;       //记录剩余芯片数Chip = 0;       //令Chip为0,后面重新计算剩余的芯片数for (int i = 1; i < n; i+=2) {       //用后一枚芯片与前一枚芯片比较,两个两个比较if(compare(chipArr,tempArr[i-1],tempArr[i])){tempArr[Chip++] = tempArr[i-1];   //如果为真,temp数组以chip为下标就记录下原数组的该芯片的下标,剩余芯片+1}}}if(Chip==3){        //若剩余芯片刚好为3,则直接判断,得出好芯片if(compare(chipArr,tempArr[0],tempArr[1])){System.out.println(tempArr[0]);}elseSystem.out.println(tempArr[2]);}elseSystem.out.println(tempArr[0]);}public static boolean compare(boolean[] chipArr, int left, int right) {      //两枚芯片互相测试if (chipArr[left] == true && chipArr[right] == true) {return true;} else if ((chipArr[left] == true && chipArr[right] == false) || (chipArr[left] == false && chipArr[right] == true)) {return false;} else {if (r.nextInt(3) == 0) { //两片芯片为坏的时候,有三分之一的概率返回测试结果为两个都为好return true;} elsereturn false;}}
}

写得不好,多请谅解!

算法分析:芯片测试问题 非递归 JAVA 有n片芯片,已知好芯片比坏芯片至少多1片......相关推荐

  1. 归并排序(非递归,Java实现)

    归并排序(非递归):自底向上 public class MergeSort {/*** @param arr 待排序的数组* @param left 本次归并的左边界* @param mid 本次归并 ...

  2. leetcode 77. Combinations-排列|递归|非递归|Java|Python

    原题链接:77. Combinations [思路-Java.Python]递归实现 采用回溯算法.这是一道 NP 难问题,时间复杂度没办法提高,用一个循环递归处理子问题,问题的终止条件是每个组合中的 ...

  3. 快排递归和非递归(java)

    思路:递归版思想没啥好说的,主要是细节,左右指针移动需要注意.这次尝试写非递归版,想的有点复杂了,其实类似树的前序遍历,细节见代码. import javafx.util.Pair; import j ...

  4. 数据结构--汉诺塔--借助栈实现非递归---Java

    1 /*汉诺塔非递归实现--利用栈 2 * 1.创建一个栈,栈中每个元素包含的信息:盘子编号,3个塔座的变量 3 * 2.先进栈,在利用循环判断是否栈空, 4 * 3.非空情况下,出栈,检查是否只有一 ...

  5. [剑指Offer]斐波那契数列、跳台阶、兔子数量问题(递归、非递归)(Java)

    剑指Offer题目 斐波那契数列 题目描述 [剑指Offer 7]大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0). [剑指Offer 8]一只青蛙 ...

  6. 二叉树中序遍历非递归Java

    问题来源与描述 问题来源:LeetCode 94,二叉树的中序遍历 思路 二叉树的中序遍历顺序是左,根,右. 使用递归比较简单: class Solution {public List<Inte ...

  7. java入门-2-【入门】已知一个圆的半径,求解该圆的面积和周长 【运算符】

    题目详情 已知一个圆的半径,求解该圆的面积和周长. 输入 输入只有一行,只有1个整数. 输出 输出只有两行,一行面积,一行周长.(保留两位小数). 令pi=3.1415926 import java. ...

  8. java 54321 5432 54 5_已知点的运动方程为

    [判断题]发达国家学制改革发展的主要趋势,从学校系统分析,双轨学制在向分支型学制和单轨学制方向发展. [判断题]<论语>内容包括:1孔子回答弟子之问.2孔子回答当时人(鲁国君等)之问.3弟 ...

  9. n个点组成多少个三角形Java,农田开发 NOJ (已知N个点选取3个求最大三角形面积问题)...

    题目描述 有一块农田,田地里安放上N个小木桩,木桩的占地面积忽略不计.选择三个小木桩,使得三个小木桩的围成的三角形占地面积最大. 输入 第一行一个整数N(3<=n<=100),便是木桩个数 ...

最新文章

  1. android unity 关闭应用_在后台运行的Android Unity应用程序
  2. oracle数据泵数据库导出导入及定时备份
  3. Dos中查找文件命令的使用find
  4. 只十分钟,唾手可得的工作机会就被我搞砸了!
  5. mqtt发布json数据_mqtt应用于进程间通信
  6. SpringHttpInvoker解析3-客户端实现
  7. UE破解及注册机下载
  8. ArcGIS的 高斯-克吕格 投影坐标系
  9. linux服务器怎么拷贝文件,linux 服务器之间拷贝文件
  10. modeler 连接oracle,用 IBM SPSS Modeler 整合不同数据库之间的数据
  11. web前端要学哪些东西?主要做什么
  12. PDF如何旋转其中一页?
  13. 用一生的漫长,等待最初的绿色
  14. 查找购买绿驹电动车配件联系方式(半小时获取)
  15. python替换指定位置word图片_用Python在word的指定位置插入图片(使用Python-docx包)...
  16. [内附完整源码和文档] 基于Qt5的国际跳棋双人网络对战游戏
  17. Nt*和Zw*开头的函数
  18. linux系统ata1.00,Linux : ata: failed command: READ FPDMA QUEUED
  19. 【前端系列教程之JavaScript】01_JavaScript概述和引入方式
  20. 太平洋皇冠证券按照2015年第四季度的收入计算,列出了全球企业云服务收入最多的10家科技公司

热门文章

  1. 获取寄存器地址的方法
  2. Notify与notifyall的区别
  3. 保护视力的台灯哪个品牌好?盘点专业性强的护眼台灯
  4. 深入解析WINDOWS操作系统 1
  5. ThinkPHP+基于ThinkPHP的图书馆管理系统 毕业设计-附源码311833
  6. 北风修仙笔记—2020年4月
  7. python--禁用、启用串口设备
  8. 到2021年1月1日的天数(包括当天)
  9. 串口通讯隔离利用光耦隔离的问题
  10. 二级建造考试复习资料-市政