问题
Right now I am working on a suite of word games as a means of teaching myself (and recreating some of my favorite word games!) With the help of an 'actual' studied programming friend, we have implemented a nice permutation method in one of my classes. It is finding all permutations from 3 letters and up and comparing them to Lists of strings I have containing what is essentially the Scrabble tournament word list.
That's the background, here is my current issue: I now have all of the permutations and have compared them to existing words and created a new List with all possible words combinations in a given string. However, when I present this string to the user, I need it to be scrambled. I found a few C# implementations of the Fisher-Yates shuffle but I was unsuccessful in adapting them to accept a single string (EDIT: Fisher-Yates issue solved with a char[] array). Then I had an idea for a little bit of a hack - why not use one of the permutations that is of the same length but is != the original word.
Unfortunately, every time my conditional statement returns the word backwards. Not that hard for the end user to figure out :) Here is my code for scrambling:
// permWords is a Dictionary<int, List<string>>
String strScrambled= "";
foreach (List<string> listWords in permWords.Values)
{
foreach (string word in listWords)
{
if (word.Length == strWord.Length && word != strWord)
{
strScrambled = word;
}
}
}
I have tried strScrambled = word + 1
assuming that the first permutation inequal to the original was the word backwards. However, I don't think that really "works" in this context; especially considering it still returns the same backwards word.
There has been a very useful answer given for how to fix my issue with Fisher-Yates using a char array, but I'm still quite curious to know how it might be best to use something like what I've posted, only finding a way to ensure that the answer is not simply the word spelled backwards. I'm intrigued by this method because the list of permutations already exists; I would like to tap into it as my solution.
回答1:
I suppose you already have a method that does the shuffling :
void FisherYatesShuffle(char[] elements)
{
int N = elements.Count;
for(int i = 0; i<N-1; i++)
{
// exchange elements[i] with a random element in i+1 .. N
}
}
All you need to do it convert your string to CharArray and than convert the result back to string:
string shuffle(string input)
{
var arr = input.ToCharArray();
FisherYatesShuffle(arr);
return new String(arr);
}
回答2:
See if this will work for you...
string str = "hello";
// The random number sequence
Random num = new Random();
string rand = str;
while (rand == str)
rand = new string(str.OrderBy(s => (num.Next())).ToArray());
If you want to make sure the shuffled value is not the exact reverse you could change the while condition to be ...
while (rand == str || rand == str.Reverse())
来源:https://stackoverflow.com/questions/13606855/fisher-yates-shuffle-on-a-single-string-vs-using-an-equal-length-permutation