如何打乱子串
How to shuffle a substring
我有一个字符串 s,大小为 kn。
我想随机播放 k n 大小的 s 块(给定 k 和 n).
示例:s = abcdabcdabcd,n = 4, k = 3.
BEGIN: abcdabcdabcd
abcd abcd abcd
└─┬─┘ └─┬─┘ └─┬─┘
shuffle shuffle shuffle
↓ ↓ ↓
bdac adbc cdba
RESULT: bdacadbccdba
Random rnd = new Random();
var s = "abcdabcdabcd";
var k = 3;
var n = 4;
var result = "";
for (int i = 0; i < k; i++)
{
var current = s.Substring((i * n), n);
var shuffled = string.Join("",current.OrderBy(x=>rnd.Next()));
result += shuffled;
}
一个结果:
"bcadabcdbcda"
一个讨厌的 Linq 语句
给定
public static Random _rnd=new Random();
public static string WeirdShuffle(string input, int n)
=> string.Concat(input.ToCharArray()
.Select((s, i) => (s, i))
.GroupBy(x => x.i / n)
.Select(g => string.Concat(g.Select(x => x.s)
.OrderBy(x => _rnd.Next()))));
用法
Console.WriteLine(WeirdShuffle("abcdabcdabcd",4));
其他资源
-
Copies the characters in this instance to a Unicode character array.
-
Projects each element of a sequence into a new form.
-
Groups the elements of a sequence.
-
Sorts the elements of a sequence in ascending order.
-
Concatenates one or more instances of String
public string Shuffle(string str, int shuffleSize)
{
if (str.Length % shuffleSize != 0)
{
throw new ArgumentException();
}
var result = Enumerable.Range(0, str.Length / shuffleSize)
.Select(i =>
SmallShuffle(str.Substring(i * shuffleSize, shuffleSize))
);
return string.Join("", result);
}
public string SmallShuffle(string str)
{
char[] array = str.ToCharArray();
Random rng = new Random();
int n = array.Length;
while (n > 1)
{
n--;
int k = rng.Next(n + 1);
var value = array[k];
array[k] = array[n];
array[n] = value;
}
return new string(array);
}
用法:
var s = "123456789123";
int k = 4;
var shuffled = Shuffle(s, k);
受这两个答案的影响很大:
像这样的东西应该有用。它本质上是经过修改的 Fisher-Yates 洗牌:
private static Random _random = new Random();
public static string ShuffleSubstrings(string input, int n, int k)
{
if (input.Length != (n * k))
{
throw new ArgumentException("Length of input is not equal to kn");
}
var characters = input.ToCharArray();
for (int g = 0; g < input.Length; g += n)
{
ShuffleSubarray(characters, g, n);
}
return new string(characters);
}
private static void ShuffleSubarray<T>(T[] array, int startPosition, int length)
{
// For loop to handle individual group
for (int i = startPosition; i < startPosition + length; ++i)
{
// shuffle taken from taken from https://www.dotnetperls.com/fisher-yates-shuffle, modified to work with groups)
int r = i + _random.Next(length - (i % length));
T tmp = array[r];
array[r] = array[i];
array[i] = tmp;
}
}
我喜欢这个:
private static Random _rnd = new Random();
public static string ShuffleSubstrings(string input, int n, int k)
{
if (input.Length != (n * k))
{
throw new ArgumentException("Length of input is not equal to kn");
}
return String.Join("",
from i in Enumerable.Range(0, k)
from x in
from y in input.Substring(i * n, n)
orderby _rnd.Next()
select y
select x);
}
static string Shffule(string str,int blockSize)
{
Random randomIndex= new Random();
for (int indexInString = 0; indexInString < str.Length; indexInString+= blockSize)
{
for (int shufflesInBlock = 0; shufflesInBlock < blockSize; shufflesInBlock++)
{
var firstRandomIndex = randomIndex.Next(indexInString, indexInString + blockSize);
var secondRandomIndex = randomIndex.Next(indexInString, indexInString + blockSize);
//str.Swap(firstRandomIndex, secondRandomIndex);
}
}
return swapedString;
}
这里有很多方法可以交换 2 个字符的字符串,所以我将把 string.Swap 扩展方法留给你
您可以通过更改 shufflesInBlock < blockSize 条件来控制嵌套循环中每个块的洗牌次数
我有一个字符串 s,大小为 kn。
我想随机播放 k n 大小的 s 块(给定 k 和 n).
示例:s = abcdabcdabcd,n = 4, k = 3.
BEGIN: abcdabcdabcd
abcd abcd abcd
└─┬─┘ └─┬─┘ └─┬─┘
shuffle shuffle shuffle
↓ ↓ ↓
bdac adbc cdba
RESULT: bdacadbccdba
Random rnd = new Random();
var s = "abcdabcdabcd";
var k = 3;
var n = 4;
var result = "";
for (int i = 0; i < k; i++)
{
var current = s.Substring((i * n), n);
var shuffled = string.Join("",current.OrderBy(x=>rnd.Next()));
result += shuffled;
}
一个结果:
"bcadabcdbcda"
一个讨厌的 Linq 语句
给定
public static Random _rnd=new Random();
public static string WeirdShuffle(string input, int n)
=> string.Concat(input.ToCharArray()
.Select((s, i) => (s, i))
.GroupBy(x => x.i / n)
.Select(g => string.Concat(g.Select(x => x.s)
.OrderBy(x => _rnd.Next()))));
用法
Console.WriteLine(WeirdShuffle("abcdabcdabcd",4));
其他资源
-
Copies the characters in this instance to a Unicode character array.
-
Projects each element of a sequence into a new form.
-
Groups the elements of a sequence.
-
Sorts the elements of a sequence in ascending order.
-
Concatenates one or more instances of String
public string Shuffle(string str, int shuffleSize)
{
if (str.Length % shuffleSize != 0)
{
throw new ArgumentException();
}
var result = Enumerable.Range(0, str.Length / shuffleSize)
.Select(i =>
SmallShuffle(str.Substring(i * shuffleSize, shuffleSize))
);
return string.Join("", result);
}
public string SmallShuffle(string str)
{
char[] array = str.ToCharArray();
Random rng = new Random();
int n = array.Length;
while (n > 1)
{
n--;
int k = rng.Next(n + 1);
var value = array[k];
array[k] = array[n];
array[n] = value;
}
return new string(array);
}
用法:
var s = "123456789123";
int k = 4;
var shuffled = Shuffle(s, k);
受这两个答案的影响很大:
像这样的东西应该有用。它本质上是经过修改的 Fisher-Yates 洗牌:
private static Random _random = new Random();
public static string ShuffleSubstrings(string input, int n, int k)
{
if (input.Length != (n * k))
{
throw new ArgumentException("Length of input is not equal to kn");
}
var characters = input.ToCharArray();
for (int g = 0; g < input.Length; g += n)
{
ShuffleSubarray(characters, g, n);
}
return new string(characters);
}
private static void ShuffleSubarray<T>(T[] array, int startPosition, int length)
{
// For loop to handle individual group
for (int i = startPosition; i < startPosition + length; ++i)
{
// shuffle taken from taken from https://www.dotnetperls.com/fisher-yates-shuffle, modified to work with groups)
int r = i + _random.Next(length - (i % length));
T tmp = array[r];
array[r] = array[i];
array[i] = tmp;
}
}
我喜欢这个:
private static Random _rnd = new Random();
public static string ShuffleSubstrings(string input, int n, int k)
{
if (input.Length != (n * k))
{
throw new ArgumentException("Length of input is not equal to kn");
}
return String.Join("",
from i in Enumerable.Range(0, k)
from x in
from y in input.Substring(i * n, n)
orderby _rnd.Next()
select y
select x);
}
static string Shffule(string str,int blockSize)
{
Random randomIndex= new Random();
for (int indexInString = 0; indexInString < str.Length; indexInString+= blockSize)
{
for (int shufflesInBlock = 0; shufflesInBlock < blockSize; shufflesInBlock++)
{
var firstRandomIndex = randomIndex.Next(indexInString, indexInString + blockSize);
var secondRandomIndex = randomIndex.Next(indexInString, indexInString + blockSize);
//str.Swap(firstRandomIndex, secondRandomIndex);
}
}
return swapedString;
}
这里有很多方法可以交换 2 个字符的字符串,所以我将把 string.Swap 扩展方法留给你
您可以通过更改 shufflesInBlock < blockSize 条件来控制嵌套循环中每个块的洗牌次数