Создание генератора случайных имен. Как мне это сделать? - PullRequest
4 голосов
/ 20 марта 2011

Я пытаюсь взять один элемент из каждого из списков здесь и объединить их, чтобы создать уникальное имя. Это только для пинки. :)

Вот списки:

List<string> FirstNames = new List<string>()
{
    "Sergio",
    "Daniel",
    "Carolina",
    "David",
    "Reina",
    "Saul",
    "Bernard",
    "Danny",
    "Dimas",
    "Yuri",
    "Ivan",
    "Laura"
};

List<string> LastNamesA = new List<string>()
{
    "Tapia",
    "Gutierrez",
    "Rueda",
    "Galviz",
    "Yuli",
    "Rivera",
    "Mamami",
    "Saucedo",
    "Dominguez",
    "Escobar",
    "Martin",
    "Crespo"
};

List<string> LastNamesB = new List<string>()
{
    "Johnson",
    "Williams",
    "Jones",
    "Brown",
    "David",
    "Miller",
    "Wilson",
    "Anderson",
    "Thomas",
    "Jackson",
    "White",
    "Robinson"
};

Я знаю, что получаю один элемент через индекс, а также знаю, что могу использовать класс Random для генерации случайного числа от 0 до ListFoo.Count.

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

Я думал об использовании класса кортежей:

List<Tuple<int,int,int>> permutations = new List<Tuple<int,int,int>>();

Но у меня тут мозговой перманент. ;) Любое руководство? Я на самом деле не ищу весь код этой простой проблемы, просто предложение или подсказку.


EDIT

Благодаря предложениям, приведенным здесь, вот что я придумала. Есть место для улучшений?

static void Main(string[] args)
{
    List<string> FirstNames = new List<string>()
    {
        "Sergio",
        "Daniel",
        "Carolina",
        "David",
        "Reina",
        "Saul",
        "Bernard",
        "Danny",
        "Dimas",
        "Yuri",
        "Ivan",
        "Laura"
    };

    List<string> LastNamesA = new List<string>()
    {
        "Tapia",
        "Gutierrez",
        "Rueda",
        "Galviz",
        "Yuli",
        "Rivera",
        "Mamami",
        "Saucedo",
        "Dominguez",
        "Escobar",
        "Martin",
        "Crespo"
    };

    List<string> LastNamesB = new List<string>()
    {
        "Johnson",
        "Williams",
        "Jones",
        "Brown",
        "David",
        "Miller",
        "Wilson",
        "Anderson",
        "Thomas",
        "Jackson",
        "White",
        "Robinson"
    };

    var permutations = new List<Tuple<int, int, int>>();
    List<string> generatedNames = new List<string>();

    Random random = new Random();
    int a, b, c;

    //We want to generate 500 names.
    while (permutations.Count < 500)
    {
        a = random.Next(0, FirstNames.Count);
        b = random.Next(0, FirstNames.Count);
        c = random.Next(0, FirstNames.Count);

        Tuple<int, int, int> tuple = new Tuple<int, int, int>(a, b, c);

        if (!permutations.Contains(tuple))
        {
            permutations.Add(tuple);
        }
    }

    foreach (var tuple in permutations)
    {
        generatedNames.Add(string.Format("{0} {1} {2}", FirstNames[tuple.Item1], 
                                                        LastNamesA[tuple.Item2],
                                                        LastNamesB[tuple.Item3])
        );
    }

    foreach (var n in generatedNames)
    {
        Console.WriteLine(n);
    }

    Console.ReadKey();
}

Ответы [ 6 ]

4 голосов
/ 20 марта 2011

Вы на правильном пути!Каждый раз, когда вы генерируете имя, добавляйте его в свой список кортежей

//Create the tuple
Tuple <int, int, int> tuple = new Tuple<int, int, int>(index1, index2, index3)

if(!permutations.Contains(tuple))
{ 
    permutations.Add(tuple);
    //Do something else
}
2 голосов
/ 20 марта 2011

Я думаю, самое простое решение - просто собрать собранное имя в HashSet<string>, что обеспечит уникальность списка созданных имен.

1 голос
/ 20 марта 2011

Сгенерировать их все очень просто с помощью LINQ:

var combs =
(from first in FirstNames
from second in LastNamesA
from third in LastNamesB
select new Tuple<string, string, string>(first, second, third)).ToList();

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

Вы можете использовать алгоритм Кнута-Фишера-Йейтса (это тасование на месте):

Random rand = new Random();

for (int i = combs.Count - 1; i > 0; i--)
{
    int n = rand.Next(i + 1);
    var mem = combs[i];
    combs[i] = combs[n];
    combs[n] = mem;
}
1 голос
/ 20 марта 2011

Альтернатива ответу HashSet состоит в том, чтобы заранее построить все возможные комбинации, перемешать их, а затем сохранить их в очереди, где вы можете получить их по одной за раз. Это позволит избежать необходимости проверять существующие каждый раз, когда вы создаете новый, и все равно будет случайным.

Это работает, только если у вас нет большого набора для начала, так как работа, связанная с созданием полного списка и его перетасовкой, будет огромной для большого набора данных.

0 голосов
/ 20 марта 2011

Я бы создал HashSet<int> и сохранил бы числовое представление пиков (например, 135 для первого, третьего и 5-го или используйте 010305), а затем проверил, есть ли они в наборе.

0 голосов
/ 20 марта 2011
  1. Создать новый кортеж с 3 случайными цифрами
  2. Проверить, содержит ли перестановка ваш новый кортеж
  3. Если нет => Добавить новый кортеж в список.Если да, начните снова с пункта 1.
...