目录
3.2假设有个函数只能返回1~5之间的随机数在不借助其它任何工具的情况下使用这个函数,获得1~7之间的随机数
3.3假设f()可以产生0或1两个数但是不是等概率的 。设返回0的概率为p;那么返回1的概率为(1-p) ,现在则需要一个等概率返回0和1的函数g()
1.数据结构
1.1数组(连续结构)
优点:便于寻址,不便于增删数据
底层并不是完全的连续结构,假设数组需要1000个空间:a有700个空间,b有300个空间,a和b之间有指针指向
1.2链表(跳转结构)
优点:便于增删,不便于寻址
2.实践:
2.1累加和数组
package com.hanlin.datastructure;
import java.util.Arrays;
/**前缀和数组
* 假设有一个数组 arr 用户总是频繁的查询arr中的某一段的累加和*/
public class PrefixArray {
private int[] preSum;
public PrefixArray(int[] arr){
int N = arr.length;
preSum = new int[N];
//第一个数不用相加
preSum[0] = arr[0];
for (int i = 1; i < N; i++) {
preSum[i] = preSum[i-1]+arr[i];
}
System.out.println(Arrays.toString(preSum));
}
public int rangeSum (int L,int R){
//如果arr等于0 就直接返回R
return L==0 ? preSum[R] : preSum[R]-preSum[L-1];
}
public static void main(String[] args) {
int[] arr ={1,2,3,4,5,6} ;
PrefixArray prefixArray = new PrefixArray(arr);
System.out.println(prefixArray.rangeSum(2,5));
}
}
3.随机数的使用
3.1将得到的[0,x)范围上的数的概率从x调整到x的平方
package com.hanlin.random;
import org.apache.hadoop.mapred.IFileOutputStream;
public class RandomNum {
//返回[0,1)的一个小数
//任意的x,x属于[0,1),[0,1)范围上的数出现的概率由原来的x调整成x的平方
public static double xToPower2(){
return Math.min(Math.random(),Math.random());
}
public static double xToPower1(){
return Math.max(Math.random(),Math.random());
}
public static void main(String[] args) {
int testTime = 10000;
int count =0;
count=0;
double x = 0.17;
for (int i =0; i<testTime;i++){
if (xToPower2()<x){
count++;
}
if (xToPower1()<x){
count++;
}
}
System.out.println((double) count/(double)testTime);
System.out.println((double) 1 - Math.pow((double) 1-x,2));
System.out.println(Math.pow(x,2));
System.out.println("=====================");
for (int i = 0; i < testTime; i++) {
if (Math.random()<0.72){
count++;
}
}
System.out.println((double) count/(double) testTime);
System.out.println("===============");
int K = 9;
int[] counts = new int[9];
for (int i = 0; i<testTime; i ++){
int ans = (int) (Math.random() * K);
counts[ans]++;
}
for (int i =0;i<K; i++){
System.out.println(i +"这个数,出现了"+counts[i]+"次");
}
}
}
3.2假设有个函数只能返回1~5之间的随机数在不借助其它任何工具的情况下使用这个函数,获得1~7之间的随机数
package com.hanlin.random;
/**
* 假设有个函数只能返回1~5之间的随机数在不借助其它任何工具的情况下使用这个函数
* 获得1~7之间的随机数*/
public class RandomNum2 {
//假设这个函数是黑盒里面的
public static int f (){
return (int)(Math.random()*5)+1;
}
//随机机制,只能用f()
//等概率返回0和1
public static int f2(){
int ans =0;
do {
ans=f();
}while (ans ==3);
return ans<3 ? 0:1;
}
//得到000~111,做到等概率
/**
* 000 001 010 100
* 011 110 101
* 111
* 共8次,做到了0~7之间等概率*/
public static int f3(){
return (f2()<<2)+(f2()<<1)+(f2()<<0);
}
public static int f4(){
int ans = 0;
do {
ans = f3();
}while (ans==7);
return ans;
}
public static int g(){
return f4()+1;
}
public static void main(String[] args) {
int[] counts = new int[8];
int times = 10000;
for (int i =0; i<times;i++){
int num = f4();
counts[num]++;
}
for (int i =0;i<8; i++){
System.out.println(i+"这个数出现了"+counts[i]+"次");
}
}
}
3.3假设f()可以产生0或1两个数但是不是等概率的 。设返回0的概率为p;那么返回1的概率为(1-p) ,现在则需要一个等概率返回0和1的函数g()
package com.hanlin.random;
/**
*假设f()可以产生0或1两个数但是不是等概率的
* 设返回0的概率为p;那么返回1的概率为(1-p)
* 现在则需要一个等概率返回0和1的函数g()*/
public class RandomNum3 {
//假设这是黑盒
public static int f(){
return Math.random()<0.84 ? 0 :1;
}
//等概率返回0和1
public static int g(){
int ans = 0;
do {
ans=f();
//ans = 0 1
//ans = 1 0
}while (ans == f());
return ans;
}
}
3.4对数器的使用
package com.hanlin.code;
import java.util.Arrays;
/**
* 对数器的使用*/
public class SelectSort {
public static void selectSort(int[] arr){
//设置边界条件
if (arr==null || arr.length<2){
return;
}
/**
* 选择排序算法
* 0~N-1上选出最小的放在0的位置
* 1~N-1上选出最小的放在1的位置
* 2~N-1上选出最小的放在2的位置
* 3~N-1上选出最小的放在3的位置
* n~N-1上选出最小的放在n的位置
* */
int N = arr.length;
//控制循环的轮数最大不能超过arr.length轮
for (int i = 0; i < N; i++) {
//将i+1后面的数拿到作比较
for (int j = i + 1; j < N; j++) {
//假设i的位置就是最小值
int minValueIndex = i;
//如果i的后一位比前一位小就将后一位的下标拿到
minValueIndex = arr[j] < arr[minValueIndex] ? j : minValueIndex;
//交换位置
swIndex(arr,minValueIndex,i);
}
}
}
public static void swIndex(int[] arr,int i,int j){
int num = arr[i];
arr[i] = arr[j];
arr[j] = num;
}
public static void printArr(int[] arr){
System.out.println(Arrays.toString(arr));
}
//生成一个随机长度和随机大小的一个数组
public static int[] gRandomArray(int maxSize,int maxValue){
int[] arr = new int[(int) ((maxSize+1) * Math.random())];
for (int i = 0; i < arr.length; i++) {
arr[i]=(int) ((maxValue+1) * Math.random())-(int)(maxValue * Math.random());
}
return arr;
}
//复制一个新数组
public static int[] copyArray(int[] arr){
if (arr==null) {
return null;
}
int[] res = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
res[i] = arr[i];
}
return res;
}
//使用数组自己带的排序方法与自己写的排序方法比交
public static void compartor(int[] arr){
Arrays.sort(arr);
}
//对数器
public static boolean isEqual(int[] arr1,int[] arr2){
if(arr1==null && arr2!=null ||(arr1!=null &&arr2==null)){
return false;
}
if (arr1==null && arr2==null) {
return true;
}
if (arr1.length!=arr2.length) {
return false;
}
for (int i = 0; i < arr1.length; i++) {
if (arr1[i]!=arr2[i]) {
return false;
}
}
return true;
}
public static void main(String[] args) {
int testTime = 3000;
int maxSize = 100;
int maxValue = 100;
boolean succeed = true;
for (int i = 0; i < testTime; i++) {
int[] arr1 = gRandomArray(maxSize,maxValue);
int[] arr2 = arr1;
selectSort(arr1);
compartor(arr2);
if (!isEqual(arr1,arr2)){
succeed = false;
printArr(arr1);
printArr(arr2);
break;
}
}
}
}