js红包算法【转载】
2024-09-04 13:41:02
源文地址:https://juejin.im/post/5ae413946fb9a07a9c03f7f7
<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head> <body>
<script>
class RandomSplit {
constructor(num) {
// 实际总数
this.num = this.getNum(num);
// 放大倍数
try {
this.multiple = this.num.toString().split('.')[1].length;
} catch (e) {
this.multiple = 0;
}
// 用于整数运算的总数
this.calcNum = this.num * Math.pow(10, this.multiple);
}
// 判断是否为number(取用至“is-number”)
isNumber(num) {
let number = +num;
if ((number - number) !== 0) {
return false;
}
if (number === num) {
return true;
}
if (typeof num === 'string') {
if (number === 0 && num.trim() === '') {
return false;
}
return true;
}
return false;
}
// 获取数字
getNum(num, defaultNum = 0) {
return this.isNumber(num) ? (+num) : defaultNum;
}
//均分份数, 均分精度, 是否直接返回放大后的整数
average(n, precision, isInt) {
precision = Math.floor(this.getNum(precision, 0));
n = Math.floor(this.getNum(n));
let calcNum = this.calcNum * Math.pow(10, precision < 0 ? 0 : precision);
// 份数超过放大后的计算总数,即不够分的情况
if (n > calcNum) {
return [];
} else {
let index = 0;
// 平均数
let avg = Math.floor(calcNum / n);
// 剩余数
let rest = calcNum % n;
// 剩余数填充间隔
let gap = Math.round((n - rest) / rest) + 1;
// 原始平均数组
let result = Array(n).fill(avg);
//
while (rest > 0) {
index = (--rest) * gap;
result[index >= n ? (n - 1) : index]++;
}
// 返回放大后的结果数组
if (isInt) {
return result;
}
// 返回处理完符合精度要求的结果数组
return result.map((item) => {
return (item / Math.pow(10, this.multiple + precision));
});
}
}
// 随机划分的份数, 划分精度
split(n, precision) {
n = Math.floor(this.getNum(n));
precision = Math.floor(this.getNum(precision, 0));
// 均分
let arr = this.average(n, precision, true);
let arrResult = arr.concat();
for (let i = 0; i < arr.length; i++) {
//给出的总额
let num = Math.floor(Math.random() * arr[i]);
// 给左邻的数额
let numLeft = Math.floor(Math.random() * num);
// 给右邻的数额
let numRight = num - numLeft;
// 首尾index处理
let iLeft = i === 0 ? (arr.length - 1) : (i - 1);
let iRight = i === (arr.length - 1) ? 0 : (i + 1);
arrResult[i] -= num;
arrResult[iLeft] += numLeft;
arrResult[iRight] += numRight;
}
// 缩小至原尺度
return arrResult.map((item) => {
return (item / Math.pow(10, this.multiple + precision));
});
}
}
var r = new RandomSplit(250);
console.log(r.average(3))
console.log(r.split(3))
</script>
</body> </html>
最新文章
- 《JavaScript高级程序设计》笔记整理
- SqlServer性能优化 即席查询(十三)
- win7下的ipython没有的问题
- Linux基本命令之逻辑测试一
- POJ-1981 Circle and Points 单位圆覆盖
- MinGW中的头文件路径级环境变量设置
- 低字节序和高字节序相互转换(Little Endian/Big Endian)
- Java中单态设计模式
- Hrbustoj 2266 Legendary Weights(辗转相除求最大公约数)
- 从Windows角度看Mac OS X上的软件开发
- Django中使用极验Geetest滑动验证码
- ogg 单表拆分合并进程
- 潭州课堂25班:Ph201805201 tornado 项目 第七课 界面美化和静态文件处理(课堂笔记)
- 0x16 Tire之最大的异或对
- Vivado HLS 工具
- 如何设置openwrt在编译linux内核时不优化内核?
- 在Windows服务器上启用TLS 1.2及TLS 1.2基本原理
- OpenLayers 官网例子的中文详解
- laravel 数据库 - 增删查改
- (转)C# Delegate.Invoke、Delegate.BeginInvoke
热门文章
- 在Android 下写一个检测软件版本号 以自动升级APP 的插件
- Hdu1828 Picture
- laravel5.1 关联模型保存的方法(使用associate方法)
- Kubernetes的Endpoints
- 一元回归_R相关系数_多重检验
- Chocolatey - Windows Software Management Automation
- centos6.5 mqtt安装
- javascript在IE下不能用 trim函数解决方法
- LintCode之二叉树的最大节点
- Problem D. Berland Railroads Gym - 101967D (思维)