Выбрать случайную строку из массива - PullRequest
26 голосов
/ 14 июля 2011

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

string[] names = { "image1.png", "image2.png", "image3.png", "image4.png", "image5.png" };

Возможно ли это?Я думал об использовании

return strings[random.Next(strings.Length)];

Но это дает возможность дважды возвращать одну и ту же строку.Или я ошибаюсь по этому поводу?Должен ли я использовать что-то еще, как List для достижения этой цели.Любые отзывы приветствуются.

Ответы [ 8 ]

38 голосов
/ 14 июля 2011

Самый простой способ (но медленный для больших списков) - использовать контейнер с изменяемыми размерами, например List, и удалить элемент после его выбора.Например:

var names = new List<string> { "image1.png", "image2.png", "image3.png", "image4.png", "image5.png" };

int index = random.Next(names.Count);
var name = names[index];
names.RemoveAt(index);
return name;

Когда ваш список пуст, все значения были выбраны.

Более быстрый способ (особенно если ваш список длинный) - использовать алгоритм перетасовки в вашем списке.Затем вы можете вывести значения по одному.Это было бы быстрее, потому что удаление с конца List обычно намного быстрее, чем удаление с середины.Что касается перетасовки, вы можете взглянуть на этот вопрос для более подробной информации.

30 голосов
/ 10 декабря 2012

Попробуйте этот код ниже

string[] Titles = { "Excellent", "Good", "Super", "REALLY GOOD DOCTOR!", "THANK YOU!", "THE BEST", "EXCELLENT PHYSICIAN", "EXCELLENT DOCTOR" };

comments_title.Value=Titles[new Random().Next(0,Titles.Length) ] ;
5 голосов
/ 14 июля 2011

Вы можете перетасовать массив на первом шаге, а затем просто выполнить итерацию по перетасованному массиву.Это имеет преимущество в том, что O (n) по сравнению с O (n ^ 2) имеют реализации на основе RemoveAt.Конечно, это не имеет большого значения для коротких массивов.

Проверьте ответ Джона Скита на следующий вопрос для хорошей (все одинаковые вероятности) реализации shuffe: Использует Random и OrderBy хорошийалгоритм перемешивания?

2 голосов
/ 14 июля 2011

Логика, которую вы можете использовать, такова:

1) Выберите случайное целое число в диапазоне, равном длине вашего массива.Вы можете сделать это с помощью класса System.Random.

2) Использовать строку, соответствующую этому индексу массива

3) Удалить элемент с этим индексом из массива (может быть проще сlist)

Затем вы можете выбрать снова, и та же строка не появится.Массив будет на один элемент короче.

2 голосов
/ 14 июля 2011

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

1 голос
/ 01 августа 2017

Используйте приведенный ниже служебный метод

public static class ListExtensions
{
    public static T PickRandom<T>(this List<T> enumerable)
    {
        int index = new Random().Next(0, enumerable.Count());
        return enumerable[index];
    }
}

Затем вызовите приведенный ниже способ

string[] fruitsArray = { "apple", "orange"};
string inputString = fruitsArray.ToList().PickRandom();
1 голос
/ 11 ноября 2012
//SET LOWERLIMIT
cmd = new SqlCommand("select min(sysid) as lowerlimit from users", cs);
int _lowerlimit = (int) cmd.ExecuteScalar();
lowerlimit = _lowerlimit;

//SET UPPERLIMIT
cmd = new SqlCommand("select max(sysid) as upperlimit from users", cs);
int _upperlimit = (int) cmd.ExecuteScalar();
upperlimit = _upperlimit;

//GENERATE RANDOM NUMBER FROM LOWERLIMIT TO UPPERLIMIT
Random rnd = new Random();
int randomNumber = rnd.Next(lowerlimit, upperlimit+1);

//DISPLAY OUTPUT
txt_output.Text += randomNumber;
1 голос
/ 14 июля 2011

Вам нужно будет отслеживать те, которые вы использовали, предпочтительно в List, если вы не хотите / не можете изменить исходный массив.Используйте цикл while, чтобы убедиться, что он не использовался, и добавьте его в список «используемых».

...