package code_04_chapter;
import java.math.BigDecimal;
/*
*Created by William on 2018/6/19 0019
*/
public class QuestionsInChapter4 {
static int[] ints = new int[10];
public QuestionsInChapter4() {
for (int i = 0; i < 10; i++) {
ints[i] = i;
}
ints[9] = 8;
ints[7] = 8;
}
/**
* 二分搜索
*/
public int binarySearch(int[] ints, int searchNumber) {
int left = 0;
int right = ints.length;
int middle;
while (left < right) {
middle = (right + left) / 2;
if (ints[middle] == searchNumber) return middle;
if (ints[middle] < searchNumber) left = middle + 1;
if (ints[middle] > searchNumber) right = middle - 1;
}
return -1;
}
public static void main(String[] args) {
QuestionsInChapter4 questionsInChapter4 = new QuestionsInChapter4();
System.out.println(questionsInChapter4.binarySearch(ints, 8));
}
/**
* Q2:
* 返回searchNumber在数组ints中第一次出现的位置。有可能t在数组中出现多次
*/
static class Q2 {
public int binarySearch2(int[] ints, int searchNumber) {
int left = 0;
int right = ints.length;
int middle = 0;
int temp;
while (left < right) {
middle = (left + right) / 2;
if (ints[middle] == searchNumber) {
temp = middle;
while (ints[temp] == ints[middle]) {
temp--;
}
return temp + 1;
}
if (ints[middle] < searchNumber) left = middle + 1;
if (ints[middle] > searchNumber) right = middle - 1;
}
return -1;
}
public static void main(String[] args) {
QuestionsInChapter4 questionsInChapter4 = new QuestionsInChapter4();
Q2 q2 = new Q2();
System.out.println(q2.binarySearch2(ints, 8));
}
}
/**
* Q3:
* 递归法写二分搜索
*/
static class Q3 {
public int binarySearch(int[] ints, int left, int right, int searchNumber) {
if (left > right) return -1;
int middle = (left + right) / 2;
if (ints[middle] == searchNumber) return middle;
if (ints[middle] < searchNumber) return binarySearch(ints, middle + 1, right, searchNumber);
if (ints[middle] > searchNumber) return binarySearch(ints, left, middle - 1, searchNumber);
return -1;
}
public static void main(String[] args) {
QuestionsInChapter4 questionsInChapter4 = new QuestionsInChapter4();
Q3 q3 = new Q3();
System.out.println(q3.binarySearch(ints, 0, ints.length, 8));
}
}
/**
* Q6:
* 选豆子问题,本题比较简单,基本思路如下:
* 首先假设黑白豆子的数量分别是black,white有三种情况:
* [1]颜色相同且都是白色豆子: white -2 , black + 1; (white >= 2)
* [2]颜色相同且都是黑色豆子: black -1;
* [3]颜色不同: black - 1; (white >=1; black >= 1)
*
* 由上方可知,豆子每次都是减少一颗,所以该过程一定会终止,最后剩下一颗;
* 由上方可知,白色豆子的减少是偶数的,所以:
* [1]存在白色豆子的数量是奇数时,最后剩下的豆子一定是白色的;
* [2]存在白色豆子的数量是偶数时,最后剩下的豆子一定是黑色的;
* [3]不存在白色豆子时,最后剩下的豆子一定是黑色的;
*/
/**
* Q7:
* 确定两条线段,还是二分搜索的思想,只是比较的过程发生了变化。
* 将相邻线段组成的区间作为一个元素,进行二分查找!
* y = a x + b
*
* 解题思路如下:
* 构成梯级的线段在y方向上是递增的,因此我们可以通过二分搜索来找到包含给定点的两条线段。
* 搜索中的基本比较说明了点在给定线段的下方,里面还是上方。
*/
/**
* Q8:
* 本书9.3节,改进二分搜索
* 返回第一个查找的字母的位置,只有一次判断,非常高效
*/
static class Q8{
public int binarySearch(int[] ints, int searchNumber) {
int left = 0;
int right = ints.length;
int halfLength;
int middle;
int len = right - left;
while (len > 0) {
halfLength = len >> 1;
middle = left + halfLength;
if(ints[middle] < searchNumber){
left = middle + 1;
len = len - halfLength -1;
}else len = halfLength;
}
if(left >= ints.length || ints[left] != searchNumber ) return -1;
return left;
}
public static void main(String[] args) {
QuestionsInChapter4 questionsInChapter4 = new QuestionsInChapter4();
Q8 q8 = new Q8();
System.out.println(q8.binarySearch(ints, 8));
}
}
/**
* Q9:
* (1)两个n维的向量相加。初开始时:i=0表示前i个维度的都已经计算好了。在循环之中,
* 计算一个维度,然后i加一,计算下一个维度,每个循环结束表明前i个维度已经计算完毕。
* i一直在增大,证明这个过程是可以终止的。当最后一个循环执行完毕的时候,i的值是n,
* 表明前n个维度已经计算好了。所以其代码是正确的。
* (2)求x数组的最大值。初开始时候,max=x[0]表示最大值是第一个数,i=1表示前i个数的最大值已经求出。
* 每次循环时候,如果有比max大的数,就替换,当循环结束时候,前i个数的最大值就知道了。
* 当整个过程结束时,i==n,所以前n个数的最大值可以求出。
* (3)当循环找个一个t的时候,就停止循环,或者当i超出范围的时候停止。i在每一次循环的时候值都增加,
* 所以这个算法是可以结束的。当超出范围的时候,返回-1,否则返回的就是第一次出现的位置,
* 因为i的值是从小到大递增的。
* (4)每次递归,问题的规模都是缩小的,所以问题可以在有限步骤内结束。
* 每次递归完成一次,就可以得到上次层想要的运算结果,接着向上传递。
*/
}
算法------编程珠玑(ProgrammingPeals)第四章习题(JAVA)
最新推荐文章于 2022-05-13 17:23:38 发布