文章目录

  • 概述
  • 随机数方法方法
    • Math.random()方法
    • Random类
  • 抢红包!!


概述

经常抢红包会发现,很大的概率是在一开始得时候抢的红包越大,越靠后越小(大概率是这种情况,这是我的经验之谈,也不是一定的)。

对于金额是如何确定的,我们可大概猜测是在用户提交之后就确定的数值,也可以是在用户每次点击的时候触发,确定金额。这两种方式并没有本质的区别。但是对于金额的确定方式,我猜测是用随机数生成的。
  
  大概思路一开始的时候,随机数取值的范围较大,出现大数的可能性更大。越往后可分配金额越少,故而金额越小(不一定,下面的demo也多次出现后面大金额的情况,我都要怀疑我的猜想了)
  
  下面先解释一下生成随机数有两种方式:Math.random()方法和Random类
  然后再分析一下抢红包的源码

随机数方法方法

Math.random()方法

该方法默认生成大于等于0.0小于1.0的double型随机数,即0<=Math.random()<=1.0,虽然只能生成0~1之间的数字,但是只要是在后面乘上一个范围值,就可以表示任意范围的数。

(int)(Math.Random()*n) ===>返回大于等于0小于n的随机数
m+(int)(Math.Random()*n) ===>返回大于等于m小于m+n(不包括m+n)的随机数

下面以一个猜数字游戏来举例说明

/**
 * 猜数字游戏
 */
import java.util.Scanner;

public class NumGame {
	public static void main(String[] args) {
		System.out.println("——————猜数字游戏——————\n");
		int iNum;
		int iGuess;
		Scanner in = new Scanner(System.in);// 创建扫描器对象,用于输入
		iNum = (int) (Math.random() * 100);// 生成1到100之间的随机数
		System.out.print("请输入你猜的数字:");
		iGuess = in.nextInt(); // 输入首次猜测的数字
		while ((iGuess != -1) && (iGuess != iNum))// 判断输入的数字不是-1或者基准数
		{
			if (iGuess < iNum)// 若猜测的数字小于基准数,则提示用户输入的数太小,并让用户重新输入
			{
				System.out.print("太小,请重新输入:");
				iGuess = in.nextInt();
			} else// 若猜测的数字大于基准数,则提示用户输入的数太大,并让用户重新输入
			{
				System.out.print("太大,请重新输入:");
				iGuess = in.nextInt();
			}
		}
		if (iGuess == -1)// 若最后一次输入的数字是-1,循环结束的原因是用户选择退出游戏
		{
			System.out.println("退出游戏!");
		} else// 若最后一次输入的数字不是-1,用户猜对数字,获得成功,游戏结束
		{
			System.out.println("恭喜你,你赢了,猜中的数字是:" + iNum);
		}
		System.out.println("\n———————游戏结束———————");
	}
}

Random类

除了Math类中的random方法外,Java中还提供了一种可以获取随机数的方式,那就是Java.util.Random类,该类表示一个随机数生成器,可以通过实例化一个Random对象来创建一个随机数生成器。

这种方式实例化对象时,Java编译器一系统当前时间作为随机数生辰器的种子,因为每时每刻的时间不可能相同,所以生成的随机数将不同,但是如果运行速度太快,也会生成两次运行结果相同的随机数。

同时还提供了各种类型随机数的方法,如下表。

方法返回值功能描述
nextInt()int返回一个随机整数
nextInt(int n)int返回一个大于0小于n的随机整数
nextLong()long返回一个随机长整型值
nextBoolean()boolean返回一个随机布尔型值
nextFloat()float返回一个随机浮点型值
nextDouble()double返回一个随机双精度型值
nextGaussian()double返回一个概率密度为高斯分布的双精度值

抢红包!!

import java.text.DecimalFormat;
import java.util.Random;
import java.util.Scanner;

/**
 * 模拟微信抢红包功能
 */
public class RedBags { //创建一个RedBags类
	public static void main(String[] args) {
		System.out.println("—————————模拟微信抢红包—————————\n"); 
		Scanner sc = new Scanner(System.in); //控制台输入
		System.out.print("请输入要装入红包的总金额(元):"); 
		double total = sc.nextDouble(); //输入“红包的总金额”
		System.out.print("请输入红包的个数(个):"); 
		int bagsnum = sc.nextInt(); //输入“红包的个数”
		double min = 0.01; //初始化“红包的最小金额”
		Random random = new Random(); //创建随机数对象random
		DecimalFormat df = new DecimalFormat("###,###,###.##"); //创建DecimalFormat类的对象df,并设置格式
		for (int i = 1; i < bagsnum; i++) { //设置“循环”,边界值是红包数-1
		//保证后面至少有(bagsnum - i) 个 最小金额可以发
			double safe = (total - (bagsnum - i) * min) / (bagsnum - i); //通过公式模拟数学中的离散模型
			double money = (double) random.nextInt((int) ((safe - min) * 100)) / 100 + min; //根据离散模型得到每个红包的金额
			total = total - money; //替换total的值
			String temp = df.format(money); //调用format()方法,对数字money格式化
			System.out.println("第" + i + "个红包:" + temp + "元"); //输出结果
		}
		String left = df.format(total); //调用format()方法,对数字total格式化
		//输出最后一个红包
		System.out.println("第" + bagsnum + "个红包:" + left + "元"); //输出结果
		sc.close(); //关闭控制台输入
	}
}

更多推荐

模拟微信抢红包demo,生成随机数