关于随机数(不重复)

方法一

一般思路,大多数人也是网上比较多的:确定一个存一个。思路比较简单,直接上摘过来的代码。

 //网上方法获取不重复随机数
    private static void testA(int sz){
        long startTime=System.currentTimeMillis(); //开始测试时间
        Random random = new Random();
        int a[] = new int[sz];//随机数组
        for (int i = 0; i < a.length; i++) {
            a[i] = random.nextInt(sz);
            for (int j = 0; j < i; j++) {
                while (a[i] == a[j]) {//如果重复,退回去重新生成随机数
                    i--;
                }
            }
        }
        long endTime=System.currentTimeMillis(); //获取结束时间 
        System.out.println("网上思路代码运行时间: "+(endTime-startTime)+"ms"); 
    }

方法二

第一种方法一般很容易想到,然后我想了想还有没有别的方法,一时间想不出来就去网上搜搜,结果大多数都是第一种,然后在一个网站上看到了一位写了另一种方法,用到了集合。先上他的代码,网站在最后贴出来。

private static void testB(int sz){
        long startTime=System.currentTimeMillis(); //开始测试时间
        Random rd = new Random();
        int[] rds = new int[sz];//随机数数组
        int n = 0;//序号
        List<Integer> lst = new ArrayList<Integer>();//存放有序数字集合
        //获取随机数数组, 里面有重复数字
        while (n < rds.length) {
            lst.add(n);
            rds[n++] = rd.nextInt(sz);
        }
        //把随机数和有序集合进行匹对, 把随机数在集合出现的数字从集合中移除掉.
        for (int i = 0; i < rds.length; i++) {
            for (int j = 0; j < lst.size(); j++) {
                if (rds[i] == lst.get(j)) {
                    lst.remove(j);
                    break;
                }
            }
        }
        //把数组中重复的第二个数字用集合的第一个数字替换掉, 并移除掉数组的第一个数字
        for (int i = 0; i < rds.length; i++) {
            for (int j = 0; j < rds.length; j++) {
                if (i != j && rds[i] == rds[j]) {
                    rds[j] = lst.get(0);
                    lst.remove(0);
                    break;
                }
            }
        }
        //得到的  rds  数组就是不重复的随机数组
        long endTime=System.currentTimeMillis(); //获取结束时间
        System.out.println("自定义代码运行时间: "+(endTime-startTime)+"ms");
    }

第三种

按照他说的比第一种方法性能要好,尤其是在数越大的时候,这个我没有测试。时我看完了还再想还有没有其他方法,因为虽然性能好,但是代码量有点多了。结果昨天临睡觉前想出来一个,很兴奋,不过在今天下午就被浇了凉水。。。这是后话了。上个方法只是把有序的十个数打乱顺序然后取出来,有时候可能需要在五十个数、一百个数、一千个数等等里面取出若干的数,上面的方法可以再优化。再得到用集合的方法的启发后,整体思路是:定义两个变量来控制随机数个数和随机数取值范围,动态定义随机数组,然后先用for循环将取值范围按顺序存入集合,也就是集合里面的数就是可以取得的随机数值。再用一个for循环来取十个数,循环内随机一个范围内的数作为下面集合里的数值的下标,然后赋值给随机数组,再将这个值从集合中移除。在这里用集合的好处体现出来了,当一个集合的一个元素被移除后,后面的会自动前移,即使下次随机的下标和上一个一样,得到的数值也不会重复。先上我自己写出来的代码。

//count是要取的随机数的个数,arround是随机数在哪个范围取 [0~arround)
public static int[] testA(int count, int arround){
        long time = System.currentTimeMillis();//依旧是测试时间。。。
        Random random = new Random();
        ArrayList<Integer> numList = new ArrayList<>();//集合存放可以取的数值范围
        int[] rand = new int[count];//随机数组
        for (int i = 1; i < arround+1; i++) {
            numList.add(i);//循环把范围内的数值顺序放入结集合
        }
        for (int i = 0; i < count; i++) {
            int n = random.nextInt(arround - i); // 随机范围内的数作为集合的下标
            rand[i] = numList.get(n); //找到这下标的数值并赋值给随机数组
            numList.remove(n);把该值从数组移除
        }
        long time2 = System.currentTimeMillis();
        System.out.println("testA运行时间: " + (time2 - time) + "ms");
        return rand;
    }

然后 

悲剧来了!! 

今天又去这个网站,然后看到了评论下面有个人也发了个方法,跟我这个差不多,但是有些一样,去看过就知道了。啊啊啊啊,,,还以为发现了新大陆。。好吧,还是太年轻。。。随机数应该还有别的方法吧,如果有人知道还望告知,谢谢!

不过思考了,就是值得的,毕竟也是靠自己(咳咳。。)写出来的~加油~

上面说的网站:https://www.cnblogs.com/weloglog888/p/5998953.html

猜你喜欢

转载自blog.csdn.net/qq_33417486/article/details/81139555