01等概率发生器、随机函数、对数器

news2025/1/19 11:28:20

1.数据结构

数据结构:是由连续结构、跳转结构或者连续加跳转(可能有多个叉)结构组成

数据结构是很多算法得以进行的载体

数组:便于寻址不便于删增数据(需要不断移动数据,如果不动可能就不是连续结构)

链表(跳转结构):便于增删数据,通过改指针(改节点)走向就可以删加数据,不便于寻址

2.前缀数组

假设有一个数组arr,用户总是频繁的查询arr中某一段的累加和
你如何组织数据,能让这种查询变得便利和快捷?

**方法一建表:**数组 [3,4,2,1,6,7,8] 适合非常频繁的拿数据,因为方法二还需要做一次减法操作

image-20230110102600538

方法二前缀和方法

数组 [3,2,-1,6,7,2,-2]

定义一个help数组 [3,5,4,10,17,19,17] H[i]表示arr从0到i的累加结果 3~7的累加和=H[7] - H[2]

如果前一个下标为0直接拿后一个下标的H[i],如果不等于0等于H[R] - H[L-1]

public static class RangeSum2 {

        private int[] preSum;

        public RangeSum2(int[] array) {
            int N = array.length;
            preSum = new int[N];
            preSum[0] = array[0];
            for (int i = 1; i < N; i++) {
                preSum[i] = preSum[i - 1] + array[i];
            }
        }

        public int rangeSum(int L, int R) {
            return L == 0 ? preSum[R] : preSum[R] - preSum[L - 1];
        }

    }

3.随机函数

1.Math.random() ->生成double类型 ->范围[0,1)

Math.random() ->生成double类型 ->范围[0,1) ;修改Math.random() < a,测试多次发现,生成的数是等概率生成的,接近a,这和数学中不一样。

public class Code02_RandToRand {
    public static void main(String[] args) {
        System.out.println("测试开始");
        int testTimes = 10000000;
        int count = 0;
        for (int i = 0;i<testTimes;i++){
            if (Math.random() <0.7){
                count ++;
            }
        }
        System.out.println((double)count / (double) testTimes);
    }
}

image-20230110105653863

2.将[0,1)变为[0,8)

将[0,1)变为[0,8) 只需要将Math.random() * 8,那么随机生成数出现百分制50的概率就应该是Math.random()*8 <4

//[0,1) -> [0,8)
        System.out.println("测试开始");
        int testTimes = 10000000;
        int count = 0;
        for (int i = 0;i<testTimes;i++){
            if (Math.random()*8 <4){
                count ++;
            }
        }
        System.out.println((double)count / (double) testTimes);
		//通过实际数来验证是否为百分制50
        System.out.println((double)4 / (double) 8);

image-20230110111334307

3.**[0,K) -> [0,8]**左右均闭合

**[0,K) -> [0,8]**左右均闭合

只需要将K赋值为9,验证等概率

		int K = 9;
		int testTimes = 10000000;
        // [0,K) -> [0,8]
        int[] counts = new int[9];
        for (int i = 0; i < testTimes; i++) {
            int answer = (int) (Math.random() * K);
            counts[answer]++;
        }
        for (int i = 0;i<K;i++){
            //这里第一个i是对应的整形数,第二个对应的是数组索引
            System.out.println(i + "这个数,出现了 " + counts[i] + " 次");
        }

每个数出现的次数差不多等概率

image-20230110112345756

4.把得到[0,x)范围上的数的概率从x调整成x^2

如果利用Math.random()函数,
把得到[0,x)范围上的数的概率从x调整成x^2

int testTimes = 10000000;
count = 0;
double x = 0.7;
for (int i = 0; i < testTimes; i++) {
    if (xToxPower2() < x) {
        count++;
    }
}
System.out.println((double) count / (double) testTimes);
System.out.println(Math.pow(x, 2));

    //返回[0,1)的一个小数
    //任意的x,x属于[0,1),[0,x)范围上的数出现概率由原来的x调整成x的平方
    public static double xToxPower2() {
        //如果要生成x^2,就需要用到max函数,因为两次生成随机数是独立的,概率都是x,所以当二者同时发生时,就会有两个max,所以就是x^2,这样也可以保证
        //生成的随机数在范围内,因为如果有其中一个不满足就会导致超出范围
        return Math.max(Math.random(), Math.random());
        
        //如果是三次方,那就是在二次方的基础上再乘一个max
        //return Math.max(Math.random(), Math.max(Math.random(),Math.random()));
    }

image-20230110163239159

5.Math.min()

如果使用的是Math.min()

应该是两次都取到1-x的平方,然后1减去就得到最小时的随机函数概率取值1-(1-x)^2

public static void main(String[] args) {
int testTimes = 10000000;
count = 0;
double x = 0.17;
for (int i = 0; i < testTimes; i++) {
    if (xToxPower3() < x) {
        count++;
    }
}
System.out.println((double) count / (double) testTimes);
System.out.println((double) 1 - Math.pow((double) 1 - x,2));

    public static double xToxPower3() {
           return Math.min(Math.random(),Math.random());
    }
}

image-20230110170349333

6.将[1,5)随机转换为0、1等概率

    public static void main(String[] args) {
        int testTimes = 10000000;
		count = 0;
        for (int i = 0;i <testTimes;i++){
            if (f2()==0){
                count++;
            }
        }
        System.out.println((double) count / (double) testTimes);
    }

	public static int f1() {
        return (int) (Math.random() * 5 + 1);
    }

    //随机体制,只能用f1,等概率返回0和1;
    public static int f2() {
        int ans = 0;
        //当f1()为3时就重复执行f1(),当f1()为1、2时为0,当f1()为4、5时为1
        do {
            ans = f1();
        }
        while (ans == 3);
        return ans < 3 ? 0 : 1;
    }

7.得到000~111 做到等概率0~7等概率返回一个

    public static void main(String[] args) {
        int testTimes = 10000000;
        int[] count1 = new int[8];
        for (int i = 0; i < testTimes; i++) {
            int num = f3();
            count1[num]++;
        }
        for (int i =0;i<8;i++){
            System.out.println(i + "这个数,出现了 " + count1[i] + " 次");
        }
    }


public static int f1() {
    return (int) (Math.random() * 5 + 1);
}

//随机体制,只能用f1,等概率返回0和1;
public static int f2() {
    int ans = 0;
    //当f1()为3时就重复执行f1(),当f1()为1、2时为0,当f1()为4、5时为1
    do {
        ans = f1();
    }
    while (ans == 3);
    return ans < 3 ? 0 : 1;
}
    //得到000~111 做到等概率0~7等概率返回一个
    public static int f3() {
        //优先级自高到低的顺序排列为:++、+、<<、<=、&&所以,优先级高的是++,优先级低的是&&。
        return (f2() << 2) + (f2() << 1) + f2();
    }
}

image-20230110184808829

8.做到等概率0~6等概率返回一个

    public static void main(String[] args) {
        int testTimes = 10000000;
        int[] count1 = new int[8];
        for (int i = 0; i < testTimes; i++) {
            int num = f3();
            count1[num]++;
        }
        for (int i =0;i<8;i++){
            System.out.println(i + "这个数,出现了 " + count1[i] + " 次");
        }
    }


public static int f1() {
    return (int) (Math.random() * 5 + 1);
}

//随机体制,只能用f1,等概率返回0和1;
public static int f2() {
    int ans = 0;
    //当f1()为3时就重复执行f1(),当f1()为1、2时为0,当f1()为4、5时为1
    do {
        ans = f1();
    }
    while (ans == 3);
    return ans < 3 ? 0 : 1;
}
    //得到000~111 做到等概率0~7等概率返回一个
    public static int f3() {
        //优先级自高到低的顺序排列为:++、+、<<、<=、&&所以,优先级高的是++,优先级低的是&&。
        return (f2() << 2) + (f2() << 1) + f2();
    }
    // 0 ~ 6等概率返回一个  当f3()为7时就重复执行f3()
    public static int f4() {
        int ans = 0;
        do {
            ans = f3();
        } while (ans == 7);
        return ans;
    }
}

image-20230110185403192

9.做到等概率1~7等概率返回一个

    public static void main(String[] args) {
        int testTimes = 10000000;
		int[] count1 = new int[8];
        for (int i = 0; i < testTimes; i++) {
            int num = g();
            count1[num]++;
        }
        for (int i =0;i<8;i++){
            System.out.println(i + "这个数,出现了 " + count1[i] + " 次");
        }
    }
	public static int f1() {
        return (int) (Math.random() * 5 + 1);
    }

    //随机体制,只能用f1,等概率返回0和1;
    public static int f2() {
        int ans = 0;
        do {
            ans = f1();
        }
        while (ans == 3);
        return ans < 3 ? 0 : 1;
    }

    //得到000~111 做到等概率0~7等概率返回一个
    public static int f3() {
        //优先级自高到低的顺序排列为:++、+、<<、<=、&&所以,优先级高的是++,优先级低的是&&。
        return (f2() << 2) + (f2() << 1) + f2();
    }
    // 0 ~ 6等概率返回一个
    public static int f4() {
        int ans = 0;
        do {
            ans = f3();
        } while (ans == 7);
        return ans;
    }
    public static int g() {
        return f4()+1;
    }
}

image-20230110214022864

10.非等概率函数变成01等概率发生器

    //这里得到0和1不是等概率的只有当p(1-p)时才是等概率的
    public static int x(){
        return Math.random() < 0.84 ? 0 : 1;
    }
    //等概率返回0和1
    public static int y(){
        int ans = 0;
        do {
            ans = x();
        }while (ans == x());//当第二次生成数等于第一次生成数,重做x(),目的在于生成p(1-p)概率事件
        // ans  = 0  1
        // ans  = 1  0
        return ans;
    }

image-20230110220059822

11.选择、冒泡、插入排序的对数器验证

过程

先生成一个随机长度的随机数组—>备份一份数组,作为样本,万一出错有样本可查–>判断第一个数组是否排序成功

为什么要备份?而不是直接相等(=)来备份?

因为如果是直接=来赋值,相当于两个数组都指向同一片内存空间,第一个已经排序好了。这里是按值传递,第一个排序改变,备份的样本不改变,不是引用传递

package class02;

import java.time.OffsetDateTime;

public class Code03_Comp {
    public static void selectSort(int[] arr) {
        //在进行选择排序之前,先判断边界条件,如果数组为空或者数组长度为2.就不需要我们进行排序
        if (arr == null || arr.length < 2) {
            return;
        }
        //其次我们在进行排序时要考虑怎么排序
        //先进行0~n-1排序 然后找到一个比0位置小的然后进行交换  然后下次排序0位置就不再进行排序了,从1位置开始,也就是1~n-1 以此类推
        //所以我们需要定义一个n也就是数组长度 然后对其进行遍历来找寻需要交换的两个元素
        int N = arr.length;
        //i为最初的最小元素位置,如果后面有比i位置元素小的元素,将会替换掉i位置所在的最小元素
        for (int i = 0; i < N; i++) {
            int minValueIndex = i;
            for (int j = i + 1; j < N; j++) {
                //j为第二个元素的位置,如果它所在位置元素比i位置所在元素小,叫交换二者位置,小于N是因为索引位置不能大于数组的长度
                minValueIndex = arr[j] > arr[minValueIndex] ? j : minValueIndex;
            }
            //最后进行二者的交换
            swap(arr, i, minValueIndex);
        }
    }

    //二:交换函数
    public static void swap(int[] arr, int i, int j) {
        int temp = arr[j];
        arr[j] = arr[i];
        arr[i] = temp;
    }

    //三:打印函数
    public static void printArray(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
    }
//=====================================================================================================================

    //返回一个数组arr,arr长度[0,maxLen-1],arr中的每个值[0,maxValue-1]
    public static int[] lenRandomValueRandom(int maxLen, int maxValue) {
        int len = (int) (Math.random() * maxLen);
        int[] ans = new int[len];
        for (int i = 0; i < len; i++) {
            ans[i] = (int) (Math.random() * maxValue);
        }
        return ans;
    }

    public static int[] copyArray(int[] arr) {
        int[] ans = new int[arr.length];
        for (int i = 0; i < arr.length; i++) {
            ans[i] = arr[i];
        }
        return ans;
    }

    public static boolean isSorted(int[] arr) {
        if (arr.length < 2) {
            return true;
        }
        int max = arr[0];
        for (int i = 0; i < arr.length; i++) {
            if (max > arr[i]) {
                return false;
            }
            max = Math.max(max, arr[i]);
        }
        //如果上面的程序满足。这一条就不再返回,如果上面不满足就同意返回true
        return true;
    }

    public static void main(String[] args) {
        int maxLen = 5;
        int maxValue = 1000;
        int testTime = 100000;
        for (int i = 0; i < testTime; i++) {
            int[] arr1 = lenRandomValueRandom(maxLen, maxValue);
            int[] temp = copyArray(arr1);
            selectSort(arr1);
            if (!isSorted(arr1)) {
                //如果排序出错,isSorted函数就返回false,取反就为true执行if语句
                System.out.println(isSorted(arr1));
                for(int j = 0;j<temp.length;j++){
                    System.out.print(temp[j]+" ");
                }
                System.out.println();
                System.out.println("选择排序出错!");
                break;
            }
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/155370.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

jupyter notebook 暗黑模式新方法

1 直接浏览器采用暗黑模式 &#xff08;1&#xff09;首先我们打开谷歌浏览器&#xff0c;在浏览器地址栏中输入“chrome://flags”然后按下回车键。 &#xff08;2&#xff09;之后我们会进入谷歌浏览器的实验室页面&#xff0c;在页面左上方的搜索框中输入“enable-force-…

DocuWare客户案例——温德姆镇使用 DocuWare Cloud 改善市民服务

DocuWare客户案例——温德姆镇使用 DocuWare Cloud 改善市民服务 新冠疫情刚开始时&#xff0c;州和地方政府除了发挥传统作用以外&#xff0c;还要负责遏制疫情的关键措施。税收和联邦援助的收入没有增加&#xff0c;跟不上这一新职责的需求。采用减轻管理负担的技术是节省资源…

2022十大边缘计算开源项目

随着“开源”被纳入“十四五”规划发展纲要&#xff0c;“支持数字技术开源社区等创新联合体发展&#xff0c;完善开源知识产权和法律体系&#xff0c;鼓励企业开放软件源代码、硬件设计和应用服务”。开源发展按下了加速键&#xff01; 开源软件生态蓬勃发展&#xff0c;边缘…

Internet结构和ISP

目录 1. ISP / IXP / ICP 定义 2. 网络连接宏观结构 3. 网络连接层级结构 4. ISP 连接方式 1. ISP / IXP / ICP 定义 ISP&#xff1a;Internet Service Provider&#xff0c;即互联网服务提供商。主要为用户提供互联网接入业务、信息业务的运营商&#xff0c;如移动和电信等。 …

数据结构学习之栈

这里写目录标题栈的定义与性质栈的实现栈的定义栈的功能栈的创建入栈出栈栈顶判断栈为空得到栈的个数栈的销毁栈的定义与性质 第一个问题&#xff1a;什么是栈&#xff1f; 栈的定义是&#xff1a; 一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。…

【从零开始学习深度学习】45. Pytorch迁移学习微调方法实战:使用微调技术进行2分类图片热狗识别模型训练【含源码与数据集】

通常为了使模型的预测精度达到较高的标准&#xff0c;需要收集十分庞大的数据集来进行模型训练。一种比较巧妙解决该问题的办法是应用迁移学习&#xff08;transfer learning&#xff09;&#xff0c;将从某个已有的数据集学到的知识迁移到目标数据集上。例如&#xff0c;假如我…

微信小程序安装 Vant 组件库与API Promise组件库并实现简单的增删改查

在项目内右键空白处选择在外部终端打开2、在终端窗口输入 npm init -y,创建package-lock.jsonnpm init -y3、在终端输入npm i vant/weapp1.3.3 -S --production&#xff0c;创建node_modules文件夹npm i vant/weapp1.3.3 -S --production4、详情&#xff0d;本地设置&#xff0…

Vue2.0开发之——Vue组件-组件的实例对象(36)

一 概述 浏览器无法直接解析Vue文件package.json中的’vue-template-compiler’将vue结尾的文件解析为js文件交给浏览器处理Count组件实例对象 二 浏览器无法直接解析Vue文件 将Vue文件拖放到浏览器中无法直接显示 三 package.json中的’vue-template-compiler’将vue结尾的文…

软件著作权登记指南

一、什么是计算机软件《计算机软件保护条例》第二条、第三条规定&#xff0c;本条例所称计算机软件&#xff08;以下简称软件&#xff09;&#xff0c;是指计算机程序及其有关文档&#xff1b;&#xff08;一&#xff09;计算机程序&#xff0c;是指为了得到某种结果而可以由计…

第13章 Token的Postman、Swagger和Vue调试

1 准备工作 1.1 WebApi.Controllers.JwtSettingModel namespace WebApi.Test { /// <summary> /// 【Jwt设置模型--纪录】 /// <remarks> /// 摘要&#xff1a; /// 通过该纪录中的属性成员实例存储“AppSettings.json”文件中的Jwt相关设置数据&#xff0…

java应用程序多级缓存架构

多级缓存架构 一级缓存&#xff1a;OpenResty—Lua—Redis 二级缓存&#xff1a;Nginx proxy-cache 三级缓存&#xff1a;Redis 使用OpenResty lua脚本访问redis proxy-cache 缓存注解 <!--依赖--> <dependency><groupId>org.springframework.boot</gr…

最新研究发现:天然海绵含有抑制Omicron变体感染的天然化合物

本文原文首发于2023年1月9日E-LIFESTYLE &#xff08;阅读时间4分钟&#xff09; 附标题&#xff1a;通过研究370多种来自植物、真菌和海绵等天然来源的化合物&#xff0c;寻找可用于治疗新冠肺炎的新抗病毒药物&#xff0c;用这些天然化合物制成的溶液中沐浴人类被SARS-CoV-2感…

SolidWorks装配体保存成零件,能有效压缩文件体积,方便二次装配

SolidWorks装配体保存成零件&#xff0c;能有效压缩文件体积&#xff0c;方便二次装配1. 先使用solidworks打开我们要转换成零件的装配体2. 然后点击上方保存下面的小三角&#xff0c;选择另存为3.之后选择要保存的位置&#xff0c;点击文件格式&#xff0c;然后在文件格式里找…

Zabbix监控服务详解+实战

目录 一、监控体系概述 1. 为什么需要监控 2. 监控目标与流程 &#xff08;1&#xff09;监控的目标 &#xff08;2&#xff09; 监控的流程 3. 监控的对象 &#xff08;1&#xff09;CPU监控 &#xff08;2&#xff09;磁盘监控 &#xff08;3&#xff09;内存监控 …

win7电脑怎么录屏?免费的录屏软件分享

现在大家的电脑一般是win10、11系统&#xff0c;但是还是有一些小伙伴喜欢使用win7系统的电脑。那你知道win7电脑怎么录屏吗&#xff1f;有没有好用且简单的win7电脑录屏软件推荐&#xff1f;当然有&#xff01;今天小编给使用win7电脑的小伙伴推荐两款简单且好用的电脑录屏软件…

各类字符串函数和内存函数的使用以及模拟(万字解析)

函数一.字符串函数(使用都需要包含string.h)1.求字符串长度—strlen2.长度不受限制的字符串函数1.strcpy-字符串拷贝2.strcat-追加字符串3.strcmp-字符串比较4.为什么长度不受限制3.长度受限制的字符串函数—strncopy,strncat,strncmp4.字符串查找1.strstr-判断是否为子字符串2…

Linux 文件句柄导致系统压力测试时出现错误率

最近&#xff0c;在对一个golang写的获取商品详情信息的接口做压力测试时&#xff0c;tps 单机可以达到1400多&#xff0c;但是发现每当压力测试开始2分钟多时就会出现502或504 错误&#xff0c;整体的错误率在0.5%左右。一开始是怀疑代码写的效率不高&#xff0c;是不是协程开…

【SAP Hana】SAP HANA SQL 进阶教程

SAP HANA SQL 进阶教程5、HANA SQL 进阶教程&#xff08;1&#xff09;Databases&#xff08;2&#xff09;User & Role&#xff08;3&#xff09;Schemas&#xff08;4&#xff09;Tables&#xff08;5&#xff09;Table Index&#xff08;6&#xff09;Table Partitions&…

于仕琪C/C++ 学习笔记

C函数指针有哪几类&#xff1f;函数指针、lambda、仿函数对象分别是什么&#xff1f;如何利用谓词对给定容器进行自定义排序&#xff1f;传递引用和传递值的区别&#xff1f;传递常引用和传递引用之间的区别&#xff1f;传递右值引用和传递引用之 间的区别&#xff1f;函数对象…

【PWA学习】6. 使用 Service Worker 进行后台同步

引言 你一定遇到过类似这样的场景&#xff1a; 当用手机填写完一张信息表单点击"提交"时&#xff0c;恰好手机网络很差或没有网络&#xff0c;这时候只能盯着手机看着旋转的小圆圈。经过长时间等待后依然没有结果&#xff0c;这时候关闭浏览器&#xff0c;请求也被终…