Как перетасовать подстроку - PullRequest
0 голосов
/ 05 февраля 2019

У меня есть строка 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

Ответы [ 6 ]

0 голосов
/ 05 февраля 2019
 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-х символов, поэтому я оставлю строку. Смените метод расширения на u

. Вы можете контролировать количество перемешиваний на блок из вложенного цикла, изменивусловие shufflesInBlock

0 голосов
/ 05 февраля 2019

Мне нравится этот:

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);
}
0 голосов
/ 05 февраля 2019

Нечто подобное должно работать.По сути, это модифицированный случай Фишера-Йейтса:

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;
    }
}

Попробуйте онлайн

0 голосов
/ 05 февраля 2019
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);

На эти два ответа сильно повлияли:

https://stackoverflow.com/a/1450797/4949005

https://stackoverflow.com/a/4740014/4949005

0 голосов
/ 05 февраля 2019

Одно противное утверждение 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));

Дополнительные ресурсы

0 голосов
/ 05 февраля 2019
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"
...