Перемешать строку С#

Я хочу знать цепочку в случайном порядке

Пример строка

string word;

//I want to shuffle it
word = "hello"  

Я мог бы получить:

rand == "ohlel"
rand == "lleho"
etc.

Ответ 1

Это решение (в форме метода расширения) приятно:

    public static string  Shuffle(this 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);
    }

Ответ 2

Вы ищете что-то вроде Fisher-Yates shuffle. На самом деле есть пример Python на этой странице:

import random

def shuffle(x):
    for i in reversed(range(1, len(x))):
        # pick an element in x[:i+1] with which to exchange x[i]
        j = random.randrange(i+1)
        x[i], x[j] = x[j], x[i]

Изменить. Поскольку ваш вопрос отмечен как ironpython, так и c#, там также есть пример Java, который очень легко конвертируется в С#.

Ответ 3

С#:

string str = "hello";

// The random number sequence
Random num = new Random();

// Create new string from the reordered char array
string rand = new string(str.ToCharArray().
                OrderBy(s => (num.Next(2) % 2) == 0).ToArray());

Ответ 4

Попробуйте Fisher-Yates Shuffle:

class Shuffle
{
    static System.Random rnd = new System.Random();

    static void Fisher_Yates(int[] array)
    {
        int arraysize = array.Length;
        int random;
        int temp;

        for (int i = 0; i < arraysize; i++)
        {
            random = i + (int)(rnd.NextDouble() * (arraysize - i));

            temp = array[random];
            array[random] = array[i];
            array[i] = temp;
        }
    }

    public static string StringMixer(string s)
    {
        string output = "";
        int arraysize = s.Length;
        int[] randomArray = new int[arraysize];

        for (int i = 0; i < arraysize; i++)
        {
            randomArray[i] = i;
        }

        Fisher_Yates(randomArray);

        for (int i = 0; i < arraysize; i++)
        {
            output += s[randomArray[i]];
        }

        return output;
    }
}

class Program
{
    static void Main()
    {
        string original = "Hello World!";

        string mixedOriginal = Shuffle.StringMixer(original);

        System.Console.WriteLine("The original string: {0}", original);
        System.Console.WriteLine("A mix of characters from the original string: {0}", mixedOriginal);

        System.Console.ReadKey();
    }
}

Ответ 5

вдохновлен порядком tsql 'by newid()

static string shuffle(string input)
{
    var q = from c in input.ToCharArray()
            orderby Guid.NewGuid()
            select c;
    string s = string.Empty;
    foreach (var r in q)
        s += r;
    return s;
}

Ответ 6

Лучший способ перетасовать строку или список строк используется таким образом. Здесь вы не получите дубликатов:

class CardsDeck
{
    public static Random r = new Random();

    private static List<string> cards = new List<string>{ "♣ King", "♣ Queen", "♣ Jack", " ♣", "♣ 7", "♣ 8", "♣ 9", "♣ 10",
                                                          "♦ King", "♦ Queen", "♦ Jack", " ♦", "♦ 7", "♦ 8", "♦ 9", "♦ 10",
                                                          "♥ King", "♥ Queen", "♥ Jack", " ♥", "♥ 7", "♥ 8", "♥ 9", "♥ 10",
                                                          "♠ King", "♠ Queen", "♠ Jack", " ♠", "♠ 7", "♠ 8", "♠ 9", "♠ 10" };
    public string ReceiveCards()
    {
        if (cards.Count > 0)
        {
            int index = r.Next(cards.Count);
            var card = cards[index];
            cards.RemoveAt(index);
            return card;
        }
        else
        {
            return "";
        }
    }
}

Ответ 7

class Program
{

    static void Main(string[] args)
    {
        string word = "hello";
        string temp = word;
        string result = string.Empty;
        Random rand = new Random();

        for (int a = 0; a < word.Length; a++)
        {
            //multiplied by a number to get a better result, it was less likely for the last index to be picked
            int temp1 = rand.Next(0, (temp.Length - 1) * 3);

            result += temp[temp1 % temp.Length];
            temp = temp.Remove(temp1 % temp.Length, 1);
        }
        Console.WriteLine(result);
    }
}

Ответ 8

Вы можете попробовать что-то вроде этого.

class Program
{
    static bool IsPositionfilled(int Position, List<int> WordPositions)
    {
        return WordPositions.Exists(a => a == Position);
    }

    public static string shufflestring(string word)
    {
        List<int> WordPositions = new List<int>();
        Random r = new Random();
        string shuffledstring = null;
        foreach (char c in word)
        {
            while (true)
            {

                int position = r.Next(word.Length);
                if (!IsPositionfilled(position, WordPositions))
                {
                    shuffledstring += word[position];
                    WordPositions.Add(position);
                    break;
                }
            }


        }
        return shuffledstring;
    }
    static void Main(string[] args)
    {

        string word = "Hel";
        Hashtable h = new Hashtable();
        for (int count = 0; count < 1000; count++)
        {
            Thread.Sleep(1);
            string shuffledstring = shufflestring(word);
            if (h.Contains(shuffledstring))
                h[shuffledstring] = ((int)h[shuffledstring]) + 1;
            else
                h.Add(shuffledstring,1);
        }

        Console.WriteLine(word);
        foreach (DictionaryEntry e in h)
        {
            Console.WriteLine(e.Key.ToString() + " , " + e.Value.ToString()); 
        }
    }
}

Ответ 9

Я выполняю это с помощью этого расширения:

public static class Extensions{
    public static string Scramble(this string s){
        return new string(s.ToCharArray().OrderBy(x=>Guid.NewGuid()).ToArray());
    }
}

Ответ 10

Следует помнить, что входная строка может содержать такие вещи, как суррогатные пары и диакритические знаки. Если это проблема, вы можете попробовать перетасовать элементы текста:

using System;
using System.Globalization;
using System.Linq;
using System.Text;

public static class StringExtensions
{
    public static string ShuffleByTextElements(this string source, Random random)
    {
        if (source == null) throw new ArgumentNullException(nameof(source));
        if (random == null) throw new ArgumentNullException(nameof(random));

        var info = new StringInfo(source);
        var indices = Enumerable.Range(0, info.LengthInTextElements).ToArray();

        // Fisher-Yates shuffle
        for (var i = indices.Length; i-- > 1;)
        {
            var j = random.Next(i + 1);
            if (i != j)
            {
                var temp = indices[i];
                indices[i] = indices[j];
                indices[j] = temp;
            }
        }

        var builder = new StringBuilder(source.Length);
        foreach (var index in indices)
        {
            builder.Append(info.SubstringByTextElements(index, 1));
        }

        return builder.ToString();
    }
}

Обратите внимание, что приведенный выше код по-прежнему не будет правильно обрабатывать некоторые функции Unicode, такие как двунаправленные переопределения, и не будет обрабатывать детали определенных сценариев, где форма буквы зависит от того, где она находится в слове. Примером этого может быть греческая строчная сигма, которая кодируется как греческая малая буква U + 03C3 (σ), за исключением конца слова, в котором вместо греческой буквы U + 03C2 используется финальная сигма (ς).

Ответ 11

Я пробовал использовать старую школу, это хорошо работает.

    static void Main()
    {        
        string input = "hello";
        string output = "";
        int ranIndex = 0;
        List<int> indexes = new List<int>();
        char[] split = input.ToCharArray();
        Random ran = new Random();

        for (int i = 0; i < input.Length; i++) 
        {
            ranIndex = ran.Next(0, input.Length);

            if (!indexes.Contains(ranIndex))
            {
                indexes.Add(ranIndex);
            }
            else 
            {
                i--;
            }
        }

        foreach (int value in indexes) 
        {
            output += split[value];
        }

            Console.WriteLine(output);
            Console.ReadLine();
    }

Ответ 12

Фишера-Йейтс

static Random rand = new Random();
public static string ShuffleString(string s)
{
    if (string.IsNullOrEmpty(s))
        return s;
    char[] chars = s.ToCharArray();
    char c;
    int j;
    for(int i = chars.Length - 1; i > 0; i--)
    {
        j = rand.Next(i + 1);  // Next max is exclusive
        if (j == i)
            continue;
        c = chars[j];
        chars[j] = chars[i];
        chars[i] = c;
    }
    return chars.ToString();
}