Shuffle string c#

蓝咒 提交于 2019-12-17 20:17:43

问题


I want to know shuffle string

Example string

string word;

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

I would be able to get:

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

回答1:


This solution (in a form of extension method) is nice:

    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:


C#:

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());



回答3:


You're looking for something like the Fisher–Yates shuffle. There's actually a Python example on that page:

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]

Edit: Since your question is tagged both ironpython and c#, there's also a Java example there which is very easily converted to C#.




回答4:


Try 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:


One thing to be aware of is that the input string may contain things like surrogate pairs and combining diacritics. If these are a concern, you may want to try shuffling text elements:

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

Note that the above code will still not handle certain Unicode features such as bidirectional overrides correctly, nor will it handle the details of certain scripts where the letter form depends on where it is in the word. An example of this would be Greek lowercase sigma, which is encoded as U+03C3 GREEK SMALL LETTER SIGMA (σ), except at the end of the word where U+03C2 GREEK SMALL LETTER FINAL SIGMA (ς) is used instead.




回答6:


inspired from tsql' order 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;
}



回答7:


The best way to shuffle a string or a list of strings is using this way. Here you will get no duplicates:

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



回答8:


I accomplish this with this extension:

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



回答9:


You could try some thing like this..

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



回答10:


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



回答11:


I tried the old school way of doing it, this one works fine.

    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:


Fisher-Yates

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


来源:https://stackoverflow.com/questions/4739903/shuffle-string-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!