-
Notifications
You must be signed in to change notification settings - Fork 0
/
allRandom.js
192 lines (178 loc) · 5.8 KB
/
allRandom.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
// 产生指定范围的随机数[lowerValue-upperValue],包括lowerValue和upperValue
// isNumber是否整型,是则返回整型,否则返回浮点型
// lowerValue,随机数下限;upperValue:随机数上线
function rangeRandom(lowerValue, upperValue, isNumber) {
if (typeof lowerValue === "number" && typeof upperValue === "number") {
var choices = isNumber
? upperValue - lowerValue + 1
: upperValue - lowerValue,
rnd = Math.random() * choices + lowerValue;
return isNumber ? Math.floor(rnd) : rnd;
}
}
/**
* 更加安全的产生指定范围的随机数
* @param {[type]} lowerValue [description]
* @param {[type]} upperValue [description]
* @param {Boolean} isNumber [description]
* @return {[type]} [description]
*/
function cryptoRandom(lowerValue, upperValue, isNumber) {
if (typeof lowerValue === "number" && typeof upperValue === "number") {
const tempRnd = crypto.getRandomValues(new Uint32Array(1))[0] / 0xffffffff;
var choices = isNumber
? upperValue - lowerValue + 1
: upperValue - lowerValue,
rnd = tempRnd * choices + lowerValue;
return isNumber ? Math.floor(rnd) : rnd;
}
}
/*
得到一个大于等于0,小于1之间的随机数
Math.random() 函数返回一个浮点, 伪随机数在范围从0到小于1,也就是说,从0(包括0)往上,但是不包括1(排除1),然后您可以缩放到所需的范围。实现将初始种子选择到随机数生成算法;它不能被用户选择或重置。
*/
function getRandom() {
return Math.random();
}
/*
得到一个两数之间的随机数
这个例子返回了一个在指定值之间的随机数。这个值不小于 min(有可能等于),并且小于(不等于)max。
*/
function getRandomArbitrary(min, max) {
return Math.random() * (max - min) + min;
}
/*
得到一个两数之间的随机整数
这个例子返回了一个在指定值之间的随机整数。这个值不小于 min (如果 min 不是整数,则不小于 min 的向上取整数),且小于(不等于)max。
*/
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min; //不含最大值,含最小值
}
/*
得到一个两数之间的随机整数,包括两个数在内
*/
function getRandomIntInclusive(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min; //含最大值,含最小值
}
// 数组乱序
function shuffle(arr) {
return arr.sort((a, b) => {
return Math.random() > 0.5 ? 1 : -1;
});
}
// 数组乱序, 这个不是真正的O(n),时间复杂度,因为有splice,平均复杂度O(n^2)
Array.prototype.random = function () {
var result = [],
arr = this,
len = arr.length;
/*for (var i = 0; i < len; i++) {
var t = Math.floor(Math.random() * arr.length);
result.push(arr[t]);
var left = arr.slice(0, t),
right = arr.slice(t + 1, arr.length);
arr = left;
arr.push.apply(arr, right);
}*/
for (var i = 0; i < len; i++) {
var t = Math.floor(Math.random() * arr.length);
result.push(arr.splice(t, 1)[0]);
}
return result;
};
// console.log(shuffle([1,2,3,4,5,6,7,8,9]));
// 真正的线性时间复杂度乱序
function shuffle2(arr = []) {
const n = arr.length;
for (let i = 0; i < n; i++) {
// 0-i之间的随机数,或者i+1到n-1之间的随机数
const r = Math.ceil(Math.random() * i);
[arr[i], arr[r]] = [arr[r], arr[i]];
}
return arr;
}
/**
* arr: 原始数组,ids
* k:随机取k个元素
* canDuplicate: arr中的元素是否可以被重复取两次+
*/
function getRand(arr = [], k = arr.length, canDuplicate = false) {
let res = [];
const n = arr.length;
if (canDuplicate) {
for (let i = 0; i < k; i++) {
const r = Math.floor(Math.random() * n);
res.push(arr[r]);
}
} else {
for (let i = 0; i < n; i++) {
// 取0-i之间的随机数,或者i+1到n-1之间的随机数
const r = Math.ceil(Math.random() * i);
// 使用解构方式交换元素,前面一句一定要有分号,否则报错
[arr[i], arr[r]] = [arr[r], arr[i]];
}
res = arr.slice(0, k);
}
return res;
}
// console.log(getRand(
// [1, 2, 3, 4, 5, 6, 7]), getRand([1, 2, 3, 4, 5, 6, 7], 3),
// getRand([1, 2, 3, 4, 5, 6, 7], 3), getRand([1, 2, 3, 4, 5, 6, 7], 3, true),
// getRand([1, 2, 3, 4, 5, 6, 7], 3, true)
// )
// 水塘随机抽样,从序列中随机抽取1个元素,线性时间复杂度
function getRandOne(head) {
let p = head;
let res = null;
let i = 0;
while (p !== null) {
// 产生[0,i)的随机数
const r = Math.floor(Math.random() * ++i);
if (r === 0) {
res = p.val;
}
p = p.next;
}
return res;
}
// 水塘随机抽样,从序列中随机抽取k个元素,线性时间复杂度
// 比如从链表中随机抽取k个元素
function getRandK(head, k) {
const p = head;
const res = [];
for (let j = 0; j < k && p !== null; j++) {
res.push(p.val);
p = p.next;
}
let i = k;
while (p !== null) {
// 产生[0,i)的数
const r = Math.floor(Math.random() * ++i);
// r 小于k的概率是k/i
if (k > r) {
res[r] = p.val;
}
p = p.next;
}
}
// 生成随机字符串,[0-9a-z]数字与字母的组合
function generateRandomAlphaNum(len = 1) {
var rdmString = "";
while (rdmString.length < len) {
const tempStr = Math.random().toString(36);
// console.log('tempStr', tempStr)
rdmString += tempStr.substr(2);
// console.log('rdmString', rdmString)
}
// console.log('out while rdmString', rdmString)
return rdmString.substr(0, len);
}
// 生成随机IP, 赋值给 X-Forwarded-For
function getRandomIP() {
return Array.from(Array(4))
.map(() => parseInt(Math.random() * 255))
.join(".");
}