Chcę wiedzieć Shuffle StringShuffle ciąg C#
Przykład ciąg
string word;
//I want to shuffle it
word = "hello"
byłbym w stanie dostać:
rand == "ohlel"
rand == "lleho"
etc.
Chcę wiedzieć Shuffle StringShuffle ciąg C#
Przykład ciąg
string word;
//I want to shuffle it
word = "hello"
byłbym w stanie dostać:
rand == "ohlel"
rand == "lleho"
etc.
Patrzysz na coś jak Fisher–Yates shuffle . Jest rzeczywiście przykładem Python na tej stronie:
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]
Edycja: Ponieważ pytanie jest oznaczone zarówno ironpython
i c#
, tam także przykład Java, który jest tam bardzo łatwo przekształcić w C#.
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());
To rozwiązanie (w formie metodę rozszerzenia) jest ładny:
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);
}
To nie jest jednolity shufflw – Paparazzi
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);
}
}
Można by spróbować coś takiego ..
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());
}
}
}
inspirowane tsql 'zamów przez 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;
}
newid jest wyjątkowy nie losowy – Paparazzi
Próbowałem starego sposobu, aby to zrobić, ten działa dobrze.
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();
}
dlaczego głosowanie w dół? – Rye
Najlepszym sposobem, aby przetasować ciąg lub listę ciągów korzysta w ten sposób. Tutaj dostaniesz żadnych duplikatów:
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 "";
}
}
}
Nie, to nie jest najlepszy sposób. Mimo że unika duplikatów, jest to bardzo nieefektywne. Wymieszanie Fisher-Yates wspomniane w innym miejscu jest o wiele lepszym sposobem na zrobienie tego. –
to osiągnąć z tego rozszerzenia:
public static class Extensions{
public static string Scramble(this string s){
return new string(s.ToCharArray().OrderBy(x=>Guid.NewGuid()).ToArray());
}
}
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();
}
}
To działało świetnie, dziękuję. –
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();
}
Działa dobrze, oprócz 'chars.ToString()' zawsze zwraca literał "System.Char []". Linia 'zwraca znaki.ToString(); 'powinno być' return new string (chars); ' –
To nie zachowuje oryginalnego zestawu, nadpisuje znaki nieużywane. –
To nie przyniesie dobrego wyniku losowego. Zgodnie z MSDN OrderBy użyje stabilnego sortowania i zachowa kolejność dla tych znaków, które mają tę samą wartość. Aby "h" w "cześć" zostało umieszczone jako ostatnie, "h" musi być "fałszywe", a pozostałe "prawdziwe". Jednak wynik będzie "elloh", co nie jest zbyt ekscytujące. http://msdn.microsoft.com/en-us/library/bb534966.aspx –