выбор случайного имени из текстового файла в окнах c # не повторяется

1

Мне было интересно, как с этим кодом работать, в настоящее время работая над системой турнирных скобок.

В настоящее время я создал comboBox, который извлекает все строки из "log.txt", в файле txt имеется 16 строк; то я создал кнопку назначения, которая должна назначать все имена в 16 текстовых ящиков User1 → User16, однако одно и то же имя не может быть повторено.

Я посмотрел на " Массив списка " и " Массив строки ", но я, похоже, застрял, так как не могу понять, что положить в код.

моя случайная кнопка выглядит так:

private void assign_Click(object sender, EventArgs e)
    {
        int x;
        Random rnd = new Random();
        x = rnd.Next(0, 16);
        User1.Text = comboBox2.Items[x].ToString();
        x = rnd.Next(0, 16);
        User2.Text = comboBox2.Items[x].ToString();
        x = rnd.Next(0, 16);
        User3.Text = comboBox2.Items[x].ToString();
        x = rnd.Next(0, 16);
        User4.Text = comboBox2.Items[x].ToString();
        and so on untill i hit 
        x = rnd.Next(0, 16);
        User16.Text = comboBox2.Items[x].ToString();
        }
Теги:
forms
winforms

4 ответа

1

Один из самых простых, но не обязательно наиболее эффективных способов сделать это состоит в том, чтобы поместить все ваши строки в List<string> и удалить их случайным образом по одному. Это будет работать намного лучше, если вы поместите все свои текстовые поля в коллекцию. Например, учитывая список строк, называемых myStrings и набор текстовых myTextboxes, называемых myTextboxes, вы можете:

for (var i=0; i < myStrings.Count; i++) 
{
    var idx = rnd.Next(0, myStrings.Count);
    myTextboxes[i].Text = myStrings[idx];    // Note: we are assuming the two collections have 
                                             // the same length
    myStrings.RemoveAt(idx);        
}

Это очень легко реализовать и очень легко получить право, но это не очень эффективно (для 16 элементов, это, вероятно, не имеет значения), потому что ваша коллекция неоднократно изменяется. Для более эффективного подхода сначала перетасуйте свои строки с помощью Shuffle Fisher-Yates, а затем просто назначьте первую запись из ваших перетасованных строк в первое текстовое поле, второе на второе и так далее.

  • 0
    Если OP может использовать Linq, получение строк в случайном порядке так же просто, как var rnd = new Random(); var randomStrings = lst.OrderBy(x => rnd.Next()); - просто будьте осторожны, чтобы не вызывать его в очень узком цикле, так как начальное число для Random() основано на времени и приведет к той же «случайной» последовательности. И вы также можете добавить .ToList() после OrderBy(...) , если вы хотите получить доступ к элементам по индексу.
0

Для этого достаточно просто.

Во-первых, вы знаете, что всего 16 единиц. Вам не нужно рандомизировать список, а скорее рандомизировать индекс, который вы используете для доступа к элементу списка. Эта часть, которую вы знаете.

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

Пример:

class Sample
{
   List<int> _usedIndexes;

   public Sample()
   {
      _usedIndexes = new List<int>();
   }   

   public int GetRandomIndex(int s, e)
   {
      Random rnd = new Random();

      //Initialize with a random number
      int x = rnd.Next(s, e);

      //While the index exists in the list of used indexes, get another random number.
      while(_usedIndexes.Exists(index => index == x))
      {
         x = rnd.Next(s, e);
      }

      //Add the number to the list of used indexes 
      _usedIndexes.Add(x);

      return x;
   }
}

Затем вы просто получаете доступ к списку имен, которые у вас есть, с индексом, который вы приобрели, следующим образом:

int unusedIndex = GetRandomIndex(0, 16);

User1.Text = comboBox2.Items[unusedIndex].ToString();
0

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

http://msdn.microsoft.com/en-us/library/cd666k3e(v=vs.110).aspx

0

Как насчет удаления каждого элемента после его выбора?

Попробуйте что-нибудь вроде

 comboBox1.Items.RemoveAt(x);

После добавления его и

x = rnd.Next(0, 16);

код будет уменьшаться до

x = rnd.Next(0, 15);

пока он не достигнет нуля. Другой подход состоял бы в том, чтобы выбрать один случайный цикл для всех заполненных (или вообще для более простого кода) и проверить, уже выбран ли он. Если вы уже выбрали, получите новый, пока он не станет другим.

Для этого вы можете использовать массив текстовых полей (хранить то, что у вас есть в массиве), и прокручивать их так же

    for(int i=0;i<16;i++)
    if(textBoxArray[i].Text==comboBox2.Items[x].toString()){
    chosen=true;
}

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню