【问题标题】:randomly splice values into array将值随机拼接到数组中
【发布时间】:2015-02-26 16:25:26
【问题描述】:

我有一个由随机生成的 ASCII 字符组成的数组“A”...和一条消息“M”。我想将消息 M 的字符插入到数组 A 中,这样 M 的字符顺序是完整的……但随机分布在整个数组 A 中。

原始数组:zH$@%@$#@$@^^#@(%*$@^&@!$^%&

样本输出:zH$@%@^t$#@$@^^h#@(%*$@^&@i!$^%&s等...

                    var randomChars = [];
                    for(var i=33;i<127;++i) {
                        var letter = document.createElement('span');
                        letter.innerHTML = String.fromCharCode(i);
                        randomChars.push(letter);
                    }

                    var message = "this is a message";
                    var rand = 0;
                    for (var i = 0; i < message.split("").length; i++) {    
                        rand = Math.floor((Math.random() * randomChars.length) + rand);
                        var letters = document.createElement('span');
                        letters.innerHTML = message.split("")[i];
                        letters.setAttribute("hidden","");
                        randomChars.splice(rand, 0, letters); 
                    }

小提琴:https://jsfiddle.net/0ftm2srz/1/

【问题讨论】:

  • 我不明白您所说的“保持消息顺序”是什么意思。一旦你打乱了数组中的字母,下一步是什么?
  • 随机分散保持消息的顺序是什么意思?像这样没有多大意义。
  • 您必须发布源数据和结果的示例。
  • 给定样本中的消息字符串在哪里?
  • 看起来很奇怪,你的随机数不应该从 0 开始你的随机数应该从你输入的最后一个字母的最后一个位置开始

标签: javascript arrays random


【解决方案1】:

使用上一个随机索引作为下一个随机生成索引的最小值(不包括)。从零开始。

不过,你最终可能会得到一些几乎没有乱七八糟的东西。 (!@#!$!@$#!@#this) 但它是随机的。

编辑更好的方法是生成 message.length 数量的唯一随机索引,按升序对它们进行排序,然后在加扰数组中的这些位置插入来自 message 的字符。

http://jsbin.com/kuzepujabo/1/edit?js,console

【讨论】:

  • 我之前也想过这个问题......我想知道为什么字母最后都聚集在一起 - 随机生成的数字超出了数组的长度
  • 这将是随机选择并按顺序排列的。如果您的消息的第一个字母被放置在数组的末尾附近,那么所有其余的字母都必须在后面,这样您就得到了“丛”。它必须是随机的吗?您可以通过将目标数组划分为一个部分来放置每个字母,然后在每个部分中随机放置一个字母并重新组合,从而做出看似随机的分布。这不是真正的随机,但它有一些随机性。你也会有一个稍微均匀的分布。
  • “随机”和“按顺序”是矛盾的,所以为了让事情井井有条,你会在某种程度上牺牲“随机性”。
  • “随机”和“按顺序”如果指的是同一事物,则相互矛盾。但在这种情况下,Random 是指将消息 M 的一个字母插入数组 A 的索引,而 In Order 是指保留消息 M 中每个字母的索引顺序,这样......如果一个字母 x 在消息 M 的索引为 0,消息 M 中的字母 y 的索引为 1,x 将始终在 y 之前插入数组 A。
  • 它们仍然是相关的。您插入 M 中的字母的索引必须部分地从先前字母的放置位置确定。你的例子说明了这一点。
【解决方案2】:

var o = {
   array: "zH$@%@$#@$@^^#@(%*$@^&@!$^%&".split(''),
   msg: "this is a message",
   randomMsgIndex: function () { return Math.floor(Math.random() * this.msg.length); },
   randomMsgChar: function () { return this.msg[this.randomMsgIndex()]; },
   //resultingArray: [],
   randomArrayIndex: function () { return Math.floor(Math.random() * this.array.length); }
}

for(var i = 0; i < o.msg.length; i++) {
  o.array.splice(o.randomArrayIndex(), 0, o.randomMsgChar());
}

console.log(o.array);

我想出了这个 - 但我认为它仍然不是你想要的 - 你可能想要一些东西来跟踪已经添加了哪些消息字符 - 所以不要添加它们两次 - 并确保整个消息 (它的所有字符)都被添加到数组中。

第 2 版,具有上述功能

var o = {
   array: "zH$@%@$#@$@^^#@(%*$@^&@!$^%&".split(''),
   msg: "this is a message",
   msgArray: function () { this.msg.split(''); },
   randomMsgIndex: function () { return Math.floor(Math.random() * this.msg.length); },
   randomMsgChar: function (i) { return this.msg[i]; },
   //resultingArray: [],
   randomArrayIndex: function () { return Math.floor(Math.random() * this.array.length); },
   stripStr: function (indexToSkip, originalStr) { 
				var result = "";
				for (var i = 0; i < originalStr.length; i++)
					if (indexToSkip != i)
					 result += originalStr[i];

				return result;
   }
}


for(var i = 0; i < o.msg.length; i++) {
  var msgRandomIndex = o.randomMsgIndex();
  o.array.splice(o.randomArrayIndex(), 0, o.randomMsgChar(msgRandomIndex));
  o.msg = o.stripStr(msgRandomIndex, o.msg);
}

console.log(o.array);

我认为它仍然不是 100%,而是朝着“优化”的解决方案 :-)

【讨论】:

    猜你喜欢
    • 2015-02-10
    • 1970-01-01
    • 2014-06-03
    • 1970-01-01
    • 2018-09-09
    • 1970-01-01
    • 2013-05-03
    • 1970-01-01
    • 2012-03-25
    相关资源
    最近更新 更多