要改变字符串,我可以使用类似的东西
String.prototype.shuffle = function () {
var arr = this.split("");
var len = arr.length;
for (var n = len - 1; n > 0; n--) {
m = Math.floor(Math.random() * (n + 1));
tmp = arr[n];
arr[n] = arr[m];
arr[m] = tmp;
}
return arr.join("");
}
但是我怎么能用n
字符随机区分它,同时保留字符串顺序?
例如:
"test" => "t-es--t"
"test" => "-t-e-st"
"test" => "te--st-"
我考虑过从字符串创建一个列表,生成一个随机数来表示索引,然后将列表向左移动,但是有更好的方法吗?
答案 0 :(得分:3)
这会将n
个字符char
随机插入字符串中。如果缺少char
,则默认为空格:
String.prototype.shuffle = function(n, char) {
var arr = this.split(''),
char= char || ' ';
while(n--) {
arr.splice(Math.floor(Math.random() * (arr.length+1)), 0, char);
}
return arr.join('');
} //shuffle
此 Fiddle 显示使用该方法的相对随机分布。
答案 1 :(得分:2)
即使我喜欢@Barmar的想法...... 您只需循环并随机化位置即可插入空格。
String.prototype.insertSpaces = function (n, char) {
var str = this;
for(var i = 0; i < n; i++){
var randPos = Math.floor(Math.random() * (str.length + 1)); // get random index to insert
str = str.substring(0, randPos) + char + str.substring(randPos, str.legnth); // insert the repeated sting
}
return str;
}
答案 2 :(得分:2)
如果你想要一个真正无偏见的解决方案,同样可能产生所有可能性,并且可以访问一个完美的随机数发生器(这是一个完整的其他主题),那么这是一个相当简单的解决方案。我们来定义一些术语:
m
=字符串中的字符数k
=您要插入的空格数(您称之为n
)考虑m = 7和k = 3的这个问题的一种解决方案:
0123456789
cab ba g e
问题本质上是从一组k
个数字中选择m+k
个不同的数字。有(m+k)!/(m!*k!)
种可能性。这是combinations的概念,类似于维基百科页面中的星星和条形问题。 (为了获得一个无偏的生成器,你需要一个随机数生成器,其状态值的数量远高于这个可能性。但我说RNG是另一个主题。)
这是Python中的一个示例,显示了所有的可能性:
import itertools
def show_all(s, k):
# show all combinations of k spaces inserted into string s
m = len(s)
for sample in itertools.combinations(range(m+k),k):
jprev = 0
out = ''
for ispace, i in enumerate(sample):
j = i-ispace # adjust index by number of spaces used
out += s[jprev:j] + ' '
jprev = j
out += s[jprev:]
yield sample, out
for sample, out in show_all('shoe',2):
print sample,':'+out+':'
输出:
(0, 1) : shoe:
(0, 2) : s hoe:
(0, 3) : sh oe:
(0, 4) : sho e:
(0, 5) : shoe :
(1, 2) :s hoe:
(1, 3) :s h oe:
(1, 4) :s ho e:
(1, 5) :s hoe :
(2, 3) :sh oe:
(2, 4) :sh o e:
(2, 5) :sh oe :
(3, 4) :sho e:
(3, 5) :sho e :
(4, 5) :shoe :
现在问题变成了产生随机组合的问题。在Python中,这是itertools recipes:
的一部分def random_combination_with_replacement(iterable, r):
"Random selection from itertools.combinations_with_replacement(iterable, r)"
pool = tuple(iterable)
n = len(pool)
indices = sorted(random.randrange(n) for i in xrange(r))
return tuple(pool[i] for i in indices))
在Javascript中,我们必须自己实现,我们可以使用Robert Floyd's algorithm for sampling without replacement:
来实现伪代码:
initialize set S to empty
for J := N-M + 1 to N do
T := RandInt(1, J)
if T is not in S then
insert T in S
else
insert J in S
使用Javascript:
function random_comb(r, n, m)
{
/* Generate a combination of m distinct random integers between 0 and n-1
using Floyd's algorithm
r: random generation function
such that r(k) generates an integer in the range [0, k-1]
*/
var S = {};
var out = [];
for (var i = 0; i < m; ++i)
{
var j = i+(n-m);
var t = r(j+1);
var item = (t in S) ? j : t;
S[item] = 1;
out.push(item);
}
return out.sort();
}
现在让我们把它们放在一起,忽略Math.random()不合适的事实:
var r = function(n) { return Math.floor(Math.random()*n); }
function random_comb(r, n, m)
{
/* Generate a combination of m distinct random integers between 0 and n-1
using Floyd's algorithm
r: random generation function
such that r(k) generates an integer in the range [0, k-1]
*/
var S = {};
var out = [];
for (var i = 0; i < m; ++i)
{
var j = i+(n-m);
var t = r(j+1);
var item = (t in S) ? j : t;
S[item] = 1;
out.push(item);
}
return out.sort();
}
function random_insert(r, s, k, c)
{
/* randomly insert k instances of character c into string s */
var m = s.length;
var S = random_comb(r, m+k, k);
var jprev = 0;
var out = '';
for (var ispace = 0; ispace < k; ++ispace)
{
var i = S[ispace];
var j = i - ispace; // adjust index by # of spaces
out += s.slice(jprev,j) + c;
jprev = j;
}
out += s.slice(jprev);
return out;
}
var word = 'shoe';
var results = [];
for (var i = 0; i < 10; ++i)
{
results.push(random_insert(r,word, 2, '-'));
}
var tally = {};
for (var i = 0; i < 100000; ++i)
{
var s = random_insert(r,word,2,'-');
tally[s] = (s in tally) ? (tally[s] + 1) : 1;
}
for (var s in tally)
{
results.push(s+": "+tally[s]);
}
for (var i = 0; i < results.length; ++i)
{
$("#results").append(results[i]+'<br>');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="results"></div>
答案 3 :(得分:0)
function addRandomSpaces(str,n,char){
for (var newstr="", i=0; i<str.length;){
if (n && Math.random()<0.5) {
newstr += char;
n--;
} else {
newstr += str[i++];
}
}
while(n--){
newstr += char;
}
return newstr;
}
这是一个循环遍历给定字符串str
的函数,在随机位置添加n
个char
个实例。如果完成后,n
项目尚未添加,则会在最后添加完成。
答案 4 :(得分:0)
String.prototype.addspace = function () {
var arr = this.split("");
var len = arr.length;
maxSp = 4;
for(var i = 0; i <= len; i++){
m = Math.floor(Math.random() * (maxSp + 1));
for(var j = 0; j < m ; j++){
arr.splice(i,0," ");
}
len += m;
i +=m;
}
return arr.join("");
}
警报( “华尼托” .addspace()洗牌());
答案 5 :(得分:0)
您可以使用切片功能插入新字符:
var x = "this is phrase";
var y = " a";
[x.slice(0,7), y, x.slice(7)].join('');
Result: this is a phrase
这样的事情:
String.prototype.shuffle2 = function() {
'use strict';
var numberOfSpaces = Math.floor(Math.random() * (this.length - 1));
var word = this;
for (var i = 0; i < numberOfSpaces; i++) {
var index = Math.floor(Math.random() * (this.length - 1));
word = [word.slice(0,index), '-', word.slice(index)].join('');
}
return word;
};
问候!