Fisher-Yates shuffle on a single string vs. using an equal length permutation?

依然范特西╮ 提交于 2019-12-22 14:02:42

问题


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

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