Метод выбора определенного случайного имени - PullRequest
1 голос
/ 15 июня 2011

Я работаю над приложением для Windows.Это приложение содержит динамический список имен, которые отображаются в форме (пользователь может добавить или удалить определенное имя).Что я хочу сделать, так это чтобы каждое имя в БД имело другое случайное имя из списка.Единственным условием является то, что для каждого имени должны быть назначены разные имена, и все имена должны использоваться только один раз.

То, что я пытался сделать, это использовать список, содержащий имена из базы данных и выбрать случайный индексиз списка и сравните его с соответствующим местом в БД.Если все по-другому, тогда удаляйте по этому индексу и так далее, пока не останется больше имен для размещения.

Но после этого я понял, что это не идеальный способ сделать это.Допустим, у меня есть 5 имен,

имя 1 случайно получает имя 3 имя 2 случайно получает имя 1 имя 3 случайно получает имя 4 имя 4 случайно получает имя 2 и ... имя 5 может получить только имя5, так что в этом случае это не работает.

Кто-нибудь имеет какие-либо идеи, как я мог бы заставить его работать?Какой другой метод я должен использовать?Количество имен около 20. Позже мне придется назначить 2 разных имени для каждого имени.Но сначала мне нужно решить эту проблему.

Любая помощь будет оценена!Я пишу на C #

Ответы [ 5 ]

2 голосов
/ 15 июня 2011

Ян побил меня этим, но вот код, который я делал, чтобы объяснить, как вам просто нужно переключить два последних, если не выбраны имена совпадают.

    static void Main(string[] args)
    {
        List<string> names = new List<string>() { "Jeff", "John", "Joe", "Jack", "Jim" };
        List<string> otherNames = new List<string>() { "Jeff", "John", "Joe", "Jack", "Jim" };

        Random r = new Random();

        for (int i = 4; i >= 0; i--)
        {
            int pick1 = r.Next(i);
            int pick2 = r.Next(i);
            while (names[pick1] == otherNames[pick2])
            {
                pick2++;
                if (pick2 >= otherNames.Count) pick2 = 0;
            }
            if (names.Count == 2)
            {
                // when you only have 2 names left, if the other names match...
                if (names[1 - pick1] == otherNames[1 - pick2])
                {
                    // swap one of the picked names
                    pick2 = 1 - pick2;
                }
            }
            Console.Write(names[pick1]); Console.Write(" != "); Console.WriteLine(otherNames[pick2]);
            names.RemoveAt(pick1);
            otherNames.RemoveAt(pick2);
        }
        Console.ReadKey();
    }
2 голосов
/ 15 июня 2011

Используйте предложенный вами метод и просто поменяйте местами последние два элемента, когда столкнетесь с проблемой, которую вы описали.

0 голосов
/ 15 июня 2011

Я думаю, было бы проще перетасовать один List<string> names, создать копию, сдвинуть копию на один элемент вниз (сделать последний элемент первым) и сопоставить имена по позиции.Вы гарантируете отсутствие дубликатов за один проход.

0 голосов
/ 15 июня 2011

Возможно, вы захотите взглянуть на эту похожую проблему или ответы на ruby ​​викторину 2 для идей.

Основной подход может состоять в том, чтобы скопировать список, перемешать копию и выстроить их в одну строку. Но это может привести к той же проблеме, что и у вас. Но затем просмотрите список, который вы можете поменять местами с каждым, ссылающимся на себя.

0 голосов
/ 15 июня 2011
while (position == 0) {
   position = randInt() % nameCount;
}

for (int i=0;i<nameCount;i++) {
   addPair(i,position);
   position++;
   if (position>=nameCount) position=0;
}

Имена в БД логически пронумерованы от 0 до nameCount-1; Идея состоит в том, что вы выбираете случайную позицию для второго имени, а затем увеличиваете ее и переворачиваете в конце.

Это псевдокод. Я не знаю C #.

Отличный вопрос!

...