rt
var a = [
[0, 1],
[2, 3],
[4, 5],
[6, 7]
];
1
oott123 2017-05-30 09:37:35 +08:00 via Android
看了你昨天的帖子,codehz 提供的方法其实不错。先把符合你要求的数据都拎出来再随机。
不要说 low,因为你要求的随机并不是真的随机… 建议把数组拍平,然后上下相邻就是下标差 2,左右相邻就是下标差 1,这样比较好考虑。 |
2
slucus OP @oott123
codehz 提供的是最简单粗暴的,但不实用啊(只适用少量数据)。。 我只是写出来 4 组数据,那如果有 10 组呢,所以把所有的可能写出来不太实际。。。 所以我现在使用的方法就是有几组数据就取几个数值,然后再把这些数值装进一个数组里进行随机,但是一直觉得这不是我想要的方法,所以一直到处提问╮(╯▽╰)╭,想看看有没有更优的方案。。 然后 low (只是想表示复杂的意思,没别的意思- -!) |
3
blankme 2017-05-30 09:54:57 +08:00 via Android
你的题目里说,取 2-3 个数,你昨天的最后回复中提到了“只能取到两组数”,而这两组数都是 4 个。
请首先确保你的题目描述清晰且正确,推荐你看这篇文章: https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/master/README-zh_CN.md 最后,关于带有条件限制的随机选取,一个常用的方法是: 选取一个,判断是否符合条件。 符合则保留,不符合则舍弃,再次选取。 直到获得所需数量的数字。 |
4
zhuzhuyule 2017-05-30 10:04:06 +08:00
1. 随机获取到 `r=0` or `r= 1`;
2.取出符合 限制条件 数据 ``` var b[4]; for ( i = 0 ; i < a.length -1 ; i++) { //取出奇偶数行,与 ①中的 r 做差值 取绝对值 b[i] = a[i][ abs(i %2 - r) ]; } ``` 3.再从数组`b`中随机取出 2,3 个数 就可以了 |
5
slucus OP @blankme
首先感谢你百忙之中来帮助我,然后关于我昨天的最后回复中提到了“只能取到两组数”,是在运行帖子里的代码以后得出的结果,然后我觉得我的题目还是挺清晰的。。。 最后关于昨天帖子里的那段代码,又有了一种更优的方案 %2 这样只要两行代码就能实现昨天的效果了。。。 |
6
slucus OP @zhuzhuyule
哈哈,我也刚找到这种方法,谢谢! 共享出来给大家 var a = [ [0, 1], [2, 3], [4, 5], [6, 7] ]; function select() { var random = Math.round(Math.random()); for (var i = 0; i < a.length; i++) { console.log(a[i][(i + Math.round(Math.random())) % 2]); } } select() |
7
zhuzhuyule 2017-05-30 10:12:22 +08:00
@slucus 我现想的,就看下自己老了么 [抠鼻]
|
8
slucus OP @zhuzhuyule 没老,依然那么 6
|
9
blankme 2017-05-30 10:21:02 +08:00 via Android
|
10
Xs0ul 2017-05-30 10:24:50 +08:00
|
11
slucus OP @blankme 对呀,这依然不是我想要的结果啊,但是至少使用 % 把之前那一长串代码给优化了,具体使用还是要进行改造的,嘿嘿
|
12
slucus OP @Xs0ul 对的,这并不是理想的方法,目前我只能做到交叉取数据(达到上下左右不相邻),然后在取到的结果进行随机,然后 0 和 6 的问题还需要继续研究,现在只有一个最粗暴的方法,就是每取到一个数就去做对比,但这样的方法明显是不可取的。。。所以还需要再好好想想
|
15
geelaw 2017-05-30 10:56:17 +08:00
什么叫“随机”?符合哪种分布?
|
19
geelaw 2017-05-30 11:13:51 +08:00 1
@slucus 你现在问的问题和
> 如何从一个非空一维数组里面随机拿一个元素出来 一样。这个问题是没有意义的,有意义的是下面这个问题 > 如何从一个非空一维数组里面 **均匀** 随机拿一个元素出来 我可以尝试猜测一下你的问题的含义: 考虑两个自然数 m、n 满足 mn > 2,考虑 S = { (a,b,c,d)∈[m]×[n]×[m]×[n]: |a-c|>1 或 |b-d|>1 或 a=c,b=d } 问如何生成 S 上的均匀分布。 这个结果和“不断同时取两个位置,如果相邻就丢弃重来”的效果会是一样的。又或者你想要的分布是另外一个分布。 如果你不说你想要什么样的分布,这个问题就是没有意义的。 |
20
slucus OP @geelaw 受教了[抱拳],其实这个问题是要配上数组看的,光靠文字很难简短的描述出来,所以我写出了数组。。。。
数组取随机数( 2 或 3 个),取到的数据上下左右不相邻? 从哪里取,恩,一个非空的数组, 取多少,2 或 3 个, 取到的数据有什么限制(要求?重点?),上下左右不相邻。 感觉还行啊。。。 |
21
geelaw 2017-05-30 11:44:33 +08:00 2
@slucus ……………………我说了这么一大段,您简略一下就完全失去含义了。
如果我总是返回 (0,0), (1,1) 这两个位置你看可以吗?肯定不可以对吧? 而且这个问题和数组本身没有什么关系,是对位置的随机。 (刚刚搞错了,没必要假设 m、n 的范围,只要是正整数即可) 回到题目,假设你要求的是我所说的那种随机,那么一个可行的方案是:先生成第一个位置,然后生成根据第一个位置生成第二个位置。 例如:用 0 为下标起点。 第一步,生成一个均匀随机位置 (a,b); 第二步算出 k = mn,设置 u=v=x=y= +∞; 第三步: - 如果 (a,b) 不是首行,k 减少 1,u=(a-1)*m+b ; - 如果 (a,b) 不是首列,k 减少 1,v=a*m+b-1 ; - 如果 (a,b) 不是末行,k 减少 1,x=(a+1)*m+b ; - 如果 (a,b) 不是末列,k 减少 1,y=a*m+b+1。 此时 k 代表剩下可以选的位置数目; 第四步:生成 0 到 k (左含右不含)的一个随机数 t ; 第五步: - 如果 t >= u,t 增加 1 ; - 如果 t >= v,t 增加 1 ; - 如果 t >= x,t 增加 1 ; - 如果 t >= y,t 增加 1 ; 第六步:设置 (c,d) = (floor(t / m), t mod m); 输出:(a,b,c,d)。 对于 3 或者更多个也有类似的方法。 另一种方法是逐步拒绝。 第一步:生成一个均匀随机的位置(a,b); 第二步:反复生成均匀随机的位置(c,d)直到(c,d)和(a,b)不是上下左右相邻; 输出:(a,b,c,d)。 |
22
imn1 2017-05-30 12:55:04 +08:00
如果确定格式是这样——每行只有两个数,这就好办了
同一列,二进制右边第一位是相同的 同一行,二进制右边第二位是相同的 抓住这两点就可以了 什么?值不一定是连续的? 我说的是位置,index 总是连续的吧? |
23
zhuzhuyule 2017-05-30 22:52:15 +08:00
@blankme 竟然不 @我,差评哟。 确实哟,看了我是老了[哭笑] !
|