算法2.分治算法 芯片判断好坏
2016-12-11 20:34
176 查看
有n片芯片,已知好芯片比坏芯片至少多1片。
现需要通过测试从中找出1片好芯片,测试方法为:将2片芯片放到测试台上,2片芯片互相测试并报告测试结果(即好或者坏);其中,好芯片的报告是正确的,坏芯片的报告是不可靠的(即可能正确、也可能错误)。
为保证使用较少的测试次数就能从中找出1片好芯片,请设计一个分治算法解决上述问题。
算法设计思路
芯片进行一一比较可能的结果为(好,好)(好,坏),其中(好,好)包括的可能性为两片芯片都是好的,也有可能两片都是坏的。
n奇数:先取出一片芯片,然后将该芯片和其余的芯片进行一一比较,若比较结果为(好,好)的次数>n/2,则该芯片为好芯片,反之则为坏芯片,将坏芯片删除后,进行n偶数
n偶数次:芯片两两比较,在结果为(好,好)中取出一片另放,以便后续继续比较,将结果为(好,坏)的都舍去。若最后的芯片片数为偶数,则继续进行n偶数,若为奇数,则进行n奇数
若结果剩余的片数为1或者2,则该芯片为好芯片。
算法实现的伪代码
功能描述:在n片芯片中找出好的芯片
输入:n>0(芯片总片数),再输入0,1。0代表坏芯片,1代表好的芯片。其中1的个数大于0的个数
输出:已经找到好的芯片,比较的次数count。
实现代码
算法运行结果及计算时间复杂度分析
T(n)=T(n/2)+n/2 O(n)=log N
体会
编写过程中犯了很多的错误,其中比较多的错误都是由于自己粗心大意,也就是基础理解不到位,例如判断一个整数是否为偶数老是爱写成/,导致了结果出现了很大的差池,最终在调试的时候发现了这个致命的错误。编写程序的时候,先把思路写下来,然后按照这个思路进行编写,感觉会比较顺手,要不然像以前一样,边写边想,老是停停顿顿,导致效率不是很高。程序写完后,测试花费了比较多的时间。很多都是要通过调试来验算自己的预算值。
现需要通过测试从中找出1片好芯片,测试方法为:将2片芯片放到测试台上,2片芯片互相测试并报告测试结果(即好或者坏);其中,好芯片的报告是正确的,坏芯片的报告是不可靠的(即可能正确、也可能错误)。
为保证使用较少的测试次数就能从中找出1片好芯片,请设计一个分治算法解决上述问题。
算法设计思路
芯片进行一一比较可能的结果为(好,好)(好,坏),其中(好,好)包括的可能性为两片芯片都是好的,也有可能两片都是坏的。
n奇数:先取出一片芯片,然后将该芯片和其余的芯片进行一一比较,若比较结果为(好,好)的次数>n/2,则该芯片为好芯片,反之则为坏芯片,将坏芯片删除后,进行n偶数
n偶数次:芯片两两比较,在结果为(好,好)中取出一片另放,以便后续继续比较,将结果为(好,坏)的都舍去。若最后的芯片片数为偶数,则继续进行n偶数,若为奇数,则进行n奇数
若结果剩余的片数为1或者2,则该芯片为好芯片。
算法实现的伪代码
功能描述:在n片芯片中找出好的芯片
输入:n>0(芯片总片数),再输入0,1。0代表坏芯片,1代表好的芯片。其中1的个数大于0的个数
输出:已经找到好的芯片,比较的次数count。
``` int find(n,int a[]){ count++; if n=1 or n=2,return true count; else if n%2!=0 EvenNum(n,int Nnew[]); else if n%2=0 OddNum(n,int Nnew[]); } 功能描述:n为偶数时,任意两片芯片进行一一比较,将比较结果为(好,好)的其中一片取出放入新的数组中,其余结果删除。 输入:n,int Nnew[] 输出:新的n,新的数组Nnew2[]; int EvenNum(n,int Nnew[]){ int k=0; for (int i=0;i<n;i+=2){ if Nnew[i]=Nnew[i+1] Nnew2[k]=Nnew[i] k++; return find(k,Nnew2[]) } } 功能描述:n为奇数时,取出其中任意一片芯片,将该芯片与其他芯片一一比较,若结果为(好,好)的次数大于n/2,则该芯片为好芯片,反之删除该芯片后进行n偶数。 输入:n,int Nnew[]; 输出:好芯片和比较次数count或者新的数组Nnew3[]; int OddNum(n, int Nnew[]){ int k=0; for (int i=1;i<n;i++){ if Nnew[0]=Nnew[i] k++; } if k>n/2 输出比较次数count else for (int j=1;j<n;j++) Nnew3[j-1]=Nnew[j] return find() }
实现代码
import java.util.*; public class main{ public static void main(String []args){ Scanner in=new Scanner(System.in); while (true){ count=0; System.out.println("输入芯片的总数n"); System.out.println("输入0或者1,0代表坏芯片,1代表好芯片"); System.out.println("其中1的个数大于0的个数"); int n=in.nextInt(); int a[] =new int ; for (int i=0;i<n;i++){ a[i]=in.nextInt(); } count=find(n,a); System.out.println("使用方法n奇数和n偶数的总次数"+count); System.out.println(); } } static int count=0; static int find(int n,int a[]){ if (n==1||n==2) return count; else if (n%2==0)//n=偶数 count=EvenNum(n,a); else if (n%2!=0)//n=奇数 count=OddNum(n,a); count++; return count; } private static int OddNum(int n, int[] Nnew) {//奇数 int k=0;//定义一个确定记录(好,好)的次数k for (int i=1;i<n;i++){ if (Nnew[0]==Nnew[i])//将第一个和其余芯片比较 k++;//记录(好,好)的次数 } int[] Nnew3 = new int[n-1];//当k<n/2,创建数组存储新的 if (k>=n/2) return count;//找到 else { for (int j=1;j<n;j++) Nnew3[j-1]=Nnew[j];//删除第一个, return find(n-1, Nnew3);//返回偶数 } } static int EvenNum(int n,int Nnew[]){//偶数 int k=0;//记录返回后芯片的个数 int[] Nnew2 = new int[n/2]; for (int i=1;i<n;i+=2){//芯片两两检验,将结果相同的取一个录入新的数组。 if (Nnew[i-1]==Nnew[i]){ Nnew2[k]=Nnew[i]; k++; } } return find(k, Nnew2);//返回find,并根据k的奇偶性重新判断 } }
算法运行结果及计算时间复杂度分析
T(n)=T(n/2)+n/2 O(n)=log N
体会
编写过程中犯了很多的错误,其中比较多的错误都是由于自己粗心大意,也就是基础理解不到位,例如判断一个整数是否为偶数老是爱写成/,导致了结果出现了很大的差池,最终在调试的时候发现了这个致命的错误。编写程序的时候,先把思路写下来,然后按照这个思路进行编写,感觉会比较顺手,要不然像以前一样,边写边想,老是停停顿顿,导致效率不是很高。程序写完后,测试花费了比较多的时间。很多都是要通过调试来验算自己的预算值。
相关文章推荐
- 请问如何检验校验码的正确,并判断算法的好坏。。
- 【cs基础】如何判断算法的好坏
- 如何判断MAX232接口芯片的好坏
- RS232芯片好坏判断
- 判断点在多边形内外的简单算法
- 如何判断集成电路的好坏
- 判断任意位数的一个数是否为Armstrong数的算法
- 用asp判断某IP是否属于一个网段的另类算法
- 后缀名判断算法
- 五子棋判断输赢的算法描述.[小糊涂的灵感]
- 分享自己推导的判断点是否落在三角形中的算法
- 常用算法设计方法之分治法
- 新发现判断一个点在多边形的最高效率算法 推荐******
- 50毫秒就判断网站设计好坏
- (转贴)反转一个字节 和 判断32位整数二进制中1的个数 的算法
- 反转一个字节 和 判断32位整数二进制中1的个数 的算法
- 算法:怎样得到两点连成的直线上的所有点(怎样判断一点是否在直线上)
- 后缀名判断算法
- 用asp判断某IP是否属于某网段的另类算法
- 要稳定!要性能!谈显卡做工好坏的判断