2.前缀,数组,对数器和随机行为

目录

1.数据结构

1.1数组(连续结构)

1.2链表(跳转结构)

2.实践:

2.1累加和数组

3.随机数的使用

3.1将得到的[0,x)范围上的数的概率从x调整到x的平方

3.2假设有个函数只能返回1~5之间的随机数在不借助其它任何工具的情况下使用这个函数,获得1~7之间的随机数

3.3假设f()可以产生0或1两个数但是不是等概率的 。设返回0的概率为p;那么返回1的概率为(1-p) ,现在则需要一个等概率返回0和1的函数g()

3.4对数器的使用


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;
            }
        }

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

欧冶渃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值