package zuochengyun.erfen.demo01;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;
public class TwoDivide {
//要求用二分法在一个长度不大于50,数值区间在【1,100】的数组中找到某个【1,100】的数,测试2万次不要出错。
public static void main(String[] args) {
int testTime = 20000;
int maxSize = 50;
int maxValue = 100;
boolean succeed = true;
//随机数产生器
Random ran = new Random();
//for循环执行测试次数
for (int i = 0; i < testTime; i++) {
//要找的目标值
int num = ran.nextInt(maxValue)+1;
//System.out.println(num);
//生成一个长度不超过50,数值区间在【1,100】的随机数组
int[] arr = generateArray(maxSize,maxValue);
//System.out.println(Arrays.toString(arr));
int a = erFen(arr,num);
//System.out.println(a);
ArrayList arrayList = bianLi(arr, num);
//System.out.println(arrayList);
succeed = arrayList.contains(a);
//如果遍历出来的索引值的集合中没有二分找到的索引值,那么就打印集合和二分找到的索引值
//并且停止循环
if(!succeed) {
System.out.println(Arrays.toString(arr));
System.out.println(a);
System.out.println(arrayList);
break;
}
System.out.println("=============");
}
System.out.println(succeed ? "Nice!" : "Fuck!");
}
//定义生成一个长度不超过特定值,数值区间在【1,特定值】的随机数组的方法
public static int[] generateArray(int maxSize, int maxValue) {
Random r = new Random();
int[] arrayA = new int[r.nextInt(maxSize)+1];
for (int i = 0; i < arrayA.length; i++) {
arrayA[i] = r.nextInt(maxValue)+1;
}
Arrays.sort(arrayA);
return arrayA;
}
//用遍历的方法在一个数组中找到num;所有num的索引值都保存在集合中;
public static ArrayList bianLi(int[] arrayA, int number) {
ArrayList arrayList = new ArrayList();
int index = -1;
for (int i = 0; i < arrayA.length; i++) {
if(arrayA[i] == number) {
index = i;
arrayList.add(index);
}
}
//如果集合为空,说明数组中没有目标值,那么就把-1放进集合中
if(null == arrayList || arrayList.size() == 0) {
arrayList.add(index);
}
return arrayList;
}
//定义一个二分查找某个数的方法
public static int erFen(int[] array, int num) {
int L = 0;
int R = array.length-1;
int index = -1;
while(L <= R) { //小于等于号必须有,否则会漏掉当Mid正好在L或R的位置的情况
int mid = L +((R -L) >> 1);
if(array[mid] == num) {
index = mid;
break;
}
else if(array[mid] < num) {
L = mid+1; //加1不要忘记
}
else {
R = mid-1; //减1不要忘记; 不然退不出循环,会一直保持L<=R
}
}
return index;
}
}