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)
猜你喜欢
转载自blog.csdn.net/weianluo/article/details/80738870
今日推荐
周排行