随机串c#

时间:2011-01-19 19:45:18

标签: c# algorithm ironpython

我想知道随机播放字符串

示例字符串

string word;

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

我能得到:

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

12 个答案:

答案 0 :(得分:14)

这个解决方案(以扩展方法的形式)很不错:

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

答案 1 :(得分:8)

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

答案 2 :(得分:5)

您正在寻找类似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]

编辑:由于您的问题都标记为ironpythonc#,因此还有一个Java示例,可以很容易地转换为C#。

答案 3 :(得分:5)

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

答案 4 :(得分:1)

受到来自tsql'的启发,由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;
}

答案 5 :(得分:1)

对字符串或字符串列表进行混洗的最佳方法是使用这种方式。在这里,您将不会重复:

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

答案 6 :(得分:1)

要注意的一件事是,输入字符串可能包含诸如代理对和变音符号组合之类的东西。如果有这些问题,您可能需要尝试改组文本元素:

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希腊小写字母SIGMA(σ),但在单词的末尾使用U + 03C2希腊小写字母FINAL SIGMA(ς)代替。 >

答案 7 :(得分:0)

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 :(得分:0)

你可以尝试这样的事情......

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 :(得分:0)

我用这个扩展来实现这个目标:

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

答案 10 :(得分:-1)

我尝试了旧学校的做法,这个工作正常。

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

答案 11 :(得分:-1)

费 - 耶茨

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