最简化随机数生成器(java)

生成随机数在JAVA中的Math类中有一个random方法可以生成,该方法生成的是一个double类型的小数,需要个位只需要*10,100以内就*100,为了保证随机数的分配均匀和尽量高的随机性,使用了多次的随机化,但总的来说效果不错但是有点麻烦,而且用法有限,对于特殊需求,比如说不需要0,或者需要35以内的随机数时就需要自己去写各种方法了,所以在这种需求下我对Math中的random方法还进行了简化,并且运行效率也更高,但虽然说是简化了但是随机性和分配性一点也没有降低,基本是一样的。

所以这算是我自己个人的工具类中的一个吧,原理也是两个互质数的线性求余,随机种子选择本地时间,但这样还不够,大家看看random源码就知道了,生成的随机数有显著的规律,所以最大的改进使用了二进制和十进制的一个转换,但并不是说一定要使用位码运算符,选取int 为种子的数据类型,当数字大于2147483648时会超出运算变成一个负数,这本身就是一个二进制的数2^31,所以再*-1,变为正数,这之间的转换已经可以算是进制的转换了,所以能得到很好的随机数,而且功能更加强大,这里有三个重载方法:

 
 
myrandom(int n)
myrandom(int n,boolean b)
myrandom(int n, int b)
n直接是需要的随机数范围(包括0),布尔b表示是否从0开始,最后一个表示从n 到 b的随机数。下面贴上方法并进行比对和测试。

package com.math.test;


import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

/*
 *数组方法
 */
public class ArrTool {

    //最大值
    public static int max (int [] arr){
        int s = arr[0];
        for (int a:arr) {
            if (a > s){
                s = a;
            }
        }
        return s;
    }

    //最大值
    public static int min (int [] arr){
        int s = arr[0];
        for (int a:arr) {
            if (a < s){
                s = a;
            }
        }
        return s;
    }

    //词数统计
    public static Map wordcount(int[] arr){
        HashSet<Integer> hs = new HashSet<>();
        Map<Integer,Integer> map=new HashMap<>();
        int count =1;
        for (int i : arr) {
            if(hs.add(i)) {
                map.put(i, count);
                continue;
            }
            map.put(i, map.get(i)+1);
        }
        return map;
    }

    //自建随机数生成器
    private static int seed = LocalDateTime.now().getSecond();
    public  static int myrandom(int n){
        seed = 37 * seed + 137;
        if (seed < 0) {
            seed *= -1;
        }
        return seed%(n+1);
    }

    //false表示不包括0
    public  static int myrandom(int n,boolean b){
        seed = 37 * seed + 137;
        if (seed < 0) {
            seed *= -1;
        }
        if (b == false) {
            return seed%n + 1;
        }
        return seed%(n+1);
    }
    //n到b范围的随机数
    public  static int myrandom(int n, int b){
        seed = 37 * seed + 137;
        if (seed < 0) {
            seed *= -1;
        }
        return seed%(b+1-n)+n;
    }

    //利用系统随机数生成器生成的数组
    public  static  int[] random1(int n){
        int [] a = new int[n];
        for (int i = 0; i < a.length; i++) {
            a[i] = (int)(Math.random()*10);
        }
        return a;
    }

    //利用自建随机数生成器生成的数组
    public  static  int[] random2(int n){
        int [] a = new int[n];
        for (int i = 0; i < a.length; i++) {
            a[i] = myrandom(5,15);
        }
        return a;
    }
    //利用自建随机数生成器生成的数组
    public  static  int[] random3(int n){
        int [] a = new int[n];
        for (int i = 0; i < a.length; i++) {
            a[i] = myrandom(15);
        }
        return a;
    }
    //利用自建随机数生成器生成的数组
    public  static  int[] random4(int n){
        int [] a = new int[n];
        for (int i = 0; i < a.length; i++) {
            a[i] = myrandom(15,false);
        }
        return a;
    }

    public static void main(String[] args) {
        int [] a = random1(100);
        int [] b = random2(100);
        int [] c = random3(100);
        int [] d = random4(100);
        System.out.println(Arrays.toString(a));
        System.out.println(Arrays.toString(b));
        System.out.println(Arrays.toString(c));
        System.out.println(Arrays.toString(d));
        System.out.println(wordcount(a));
        System.out.println(wordcount(b));
        System.out.println(wordcount(c));
        System.out.println(wordcount(d));
    }
}
结果为

[1, 8, 3, 8, 6, 6, 3, 6, 7, 4, 8, 4, 9, 8, 1, 7, 7, 5, 4, 1, 5, 1, 9, 8, 5, 2, 6, 1, 7, 8, 5, 9, 3, 5, 1, 7, 4, 4, 1, 7, 0, 8, 0, 2, 0, 3, 9, 3, 7, 1, 7, 4, 9, 2, 5, 6, 4, 1, 8, 0, 5, 8, 4, 5, 4, 9, 3, 4, 8, 3, 2, 6, 5, 9, 8, 8, 4, 4, 6, 6, 5, 5, 3, 4, 6, 3, 9, 7, 0, 1, 3, 6, 1, 7, 9, 4, 4, 5, 4, 5]
[15, 6, 14, 13, 5, 8, 7, 10, 5, 10, 10, 9, 9, 7, 12, 11, 9, 10, 7, 7, 9, 7, 6, 13, 8, 14, 5, 6, 11, 14, 8, 5, 9, 13, 7, 15, 14, 7, 15, 13, 6, 8, 10, 13, 6, 13, 9, 15, 14, 14, 14, 8, 7, 15, 11, 15, 12, 14, 12, 15, 14, 5, 13, 7, 11, 14, 15, 13, 10, 6, 11, 6, 14, 7, 14, 8, 14, 7, 11, 11, 6, 11, 12, 6, 9, 10, 10, 13, 10, 6, 14, 13, 12, 6, 6, 5, 15, 8, 8, 13]
[15, 12, 5, 14, 15, 12, 11, 0, 7, 12, 5, 2, 3, 8, 1, 14, 1, 2, 13, 6, 7, 4, 3, 8, 15, 12, 5, 14, 15, 12, 5, 14, 15, 12, 11, 0, 7, 4, 13, 10, 11, 0, 7, 12, 5, 2, 3, 8, 1, 2, 3, 8, 15, 12, 11, 0, 9, 6, 7, 4, 3, 8, 15, 4, 3, 8, 1, 2, 3, 8, 15, 12, 11, 0, 9, 10, 5, 2, 13, 10, 11, 0, 7, 12, 11, 0, 7, 4, 13, 10, 5, 2, 3, 8, 15, 12, 11, 0, 7, 12]
[2, 8, 12, 13, 10, 11, 2, 7, 11, 11, 5, 6, 10, 7, 10, 14, 1, 11, 14, 1, 15, 5, 4, 11, 3, 9, 5, 7, 13, 1, 11, 3, 3, 7, 15, 12, 13, 6, 8, 6, 12, 9, 5, 15, 1, 13, 1, 8, 9, 4, 3, 15, 11, 6, 12, 4, 6, 10, 8, 7, 1, 4, 5, 5, 1, 13, 6, 4, 4, 8, 2, 2, 10, 6, 8, 12, 8, 8, 7, 15, 2, 12, 10, 11, 5, 9, 11, 13, 3, 1, 4, 7, 14, 3, 14, 5, 13, 14, 11, 13]
{0=5, 1=11, 2=4, 3=10, 4=16, 5=13, 6=10, 7=10, 8=12, 9=9}                                                                     Math.random()*10
{5=6, 6=12, 7=11, 8=8, 9=7, 10=9, 11=8, 12=5, 13=11, 14=14, 15=9}                                                      myrandom(5,15)
{0=8, 1=4, 2=7, 3=8, 4=5, 5=7, 6=2, 7=8, 8=8, 9=2, 10=4, 11=8, 12=12, 13=4, 14=4, 15=9}               myrandom(15)
{1=8, 2=5, 3=6, 4=7, 5=8, 6=7, 7=7, 8=8, 9=4, 10=6, 11=10, 12=6, 13=8, 14=5, 15=5}                        myrandom(15,false)

为了方便展示只取了100个数,当数组不断扩大时测试结果越接近平均水平,并且和系统只带的高随机方法完全没有区别,证明是完全可以直接使用的,而且三个方法基本包含了随机数的90%以上的用法,其中对于质数的选择并不是唯一的,但也不是所有的质数对都可以,质数过大性能会下降甚至达不到要求,其中int 也可替换long等类型,但也是性能下降。max方法和min没用上,懒得删了就不要管了。

猜你喜欢

转载自blog.csdn.net/m15682532244/article/details/78545827