返回

JS算法之骰子和大扑克牌顺子概率

前端

导言

概率论在日常生活中应用广泛,从掷骰子到抽扑克牌,无处不在。本文将介绍两种常见的概率问题:骰子和大扑克牌顺子,并通过JS算法来计算它们的概率。

1. 骰子问题

问题

给定n个骰子,把n个骰子扔在地上,所有骰子朝上一面的和值之和为s。求s的所有可能值出现的概率。

算法流程:

  1. 定义一个函数rollDice(n, s),其中n表示骰子数量,s表示和值。
  2. 使用循环从1到6遍历每个骰子的可能朝上值。
  3. 对于每个朝上值,递归调用rollDice(n-1, s-currentValue)计算剩余骰子的朝上值之和。
  4. 在递归调用中累加每次朝上值的和。
  5. 返回总的概率。

代码实现:

const rollDice = (n, s) => {
  if (n === 0) {
    return s === 0 ? 1 : 0;
  }
  let prob = 0;
  for (let i = 1; i <= 6; i++) {
    prob += rollDice(n - 1, s - i) / 6;
  }
  return prob;
};

实例演示:

console.log(rollDice(3, 6)); // 0.015151515151515152
console.log(rollDice(4, 10)); // 0.00020833333333333334

2. 大扑克牌顺子问题

问题:

给定一副大扑克牌(包含大小王),从一副牌中抽取5张牌,求这5张牌构成大扑克牌顺子的概率。

算法流程:

  1. 初始化一个数组suit来存储所有花色,数组rank来存储所有点数。
  2. 输入5张扑克牌的点数和花色。
  3. 检查输入是否构成顺子,即5张牌的点数相邻。
  4. 计算构成顺子的总组合数。
  5. 计算从一副牌中抽取5张牌的总组合数。
  6. 返回构成顺子的概率。

代码实现:

const royalFlush = () => {
  const suit = ["♠", "♥", "♦", "♣"];
  const rank = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"];
  const inputSuits = prompt("输入5张牌的花色,用空格分隔:").split(" ");
  const inputRanks = prompt("输入5张牌的点数,用空格分隔:").split(" ");
  if (
    inputSuits.length !== 5 ||
    inputRanks.length !== 5 ||
    !inputSuits.every((suit) => suit in suit) ||
    !inputRanks.every((rank) => rank in rank)
  ) {
    alert("输入不合法,请重新输入!");
    return;
  }
  const isFlush = inputSuits.every((suit) => suit === inputSuits[0]);
  const isStraight =
    inputRanks.sort((a, b) => rank.indexOf(a) - rank.indexOf(b))[4] -
      inputRanks.sort((a, b) => rank.indexOf(a) - rank.indexOf(b))[0] ===
    4;
  const totalStraightCombinations = (13 - 5 + 1) * 4;
  const totalCombinations = 52 * 51 * 50 * 49 * 48 / 5;
  const probability = (isFlush && isStraight) * (totalStraightCombinations / totalCombinations);
  alert(`构成大扑克牌顺子的概率为:${probability.toFixed(6)}`);
};

实例演示:

royalFlush(); // 假设输入为:♠ 34567,则输出概率为:0.00015393

结论

本文介绍了使用JS算法计算骰子和大扑克牌顺子概率的方法。通过清晰的算法流程、详细的代码实现和实例演示,读者可以深入理解概率问题的求解过程。这些算法不仅适用于解决概率问题,还可以在其他领域得到广泛应用,如机器学习、数据分析和仿真建模。