我想知道洗牌串
例如串
string word;
//I want to shuffle it
word = "hello"
我将能够得到:
rand == "ohlel"
rand == "lleho"
etc.
将该溶液(在扩展方法的一种形式)是好的:
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);
}
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);
}
}
我试着做它的老同学的方式,这个工作正常。
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();
}
费雪耶茨
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();
}
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());
您正在寻找类似的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的例子有哪些是很容易转换为C#。
尝试费雪耶茨洗牌:
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();
}
}
通过从NEWID TSQL”顺序启发()
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;
}
洗牌字符串或字符串列表的最好方法是使用这种方式。在这里,你会得到不重复:
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 "";
}
}
}
我做到这一点与此扩展:
public static class Extensions{
public static string Scramble(this string s){
return new string(s.ToCharArray().OrderBy(x=>Guid.NewGuid()).ToArray());
}
}
有一点需要注意的是,输入字符串可能包含的东西像代理对和组合变音符号。如果这些是一个问题,你可能想尝试洗牌文本元素:
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 GREEK SMALL LETTER SIGMA(σ),除了在其中U + 03C2 GREEK小写字母FINAL SIGMA(ς)代替所使用的单词的末尾。
你可以尝试这样的事情..
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());
}
}
}