ASP.NET Core 2.0
Установить
PM> Install-Package AspNetCore.IServiceCollection.AddIUrlHelper
Использовать
public void ConfigureServices(IServiceCollection services)
{
...
services.AddUrlHelper();
...
}
Отказ от ответственности: автор этого пакета
int size = myHashSet.size();
int item = new Random().nextInt(size); // In real life, the Random object should be rather more shared than this
int i = 0;
for(Object obj : myhashSet)
{
if (i == item)
return obj;
i++;
}
PHP, с помощью MT:
$items_array = array("alpha", "bravo", "charlie");
$last_pos = count($items_array) - 1;
$random_pos = mt_rand(0, $last_pos);
$random_item = $items_array[$random_pos];
Если Вы хотите сделать это в Java, необходимо рассмотреть копирование элементов в некоторый набор произвольного доступа (таких как ArrayList). Поскольку, если Ваш набор не является маленьким, получая доступ к выбранному элементу, будет дорогим (O (n) вместо O (1)). [редактор: копия списка также O (n)]
, С другой стороны, Вы могли искать другую реализацию Набора, которая более тесно соответствует Вашим требованиям. ListOrderedSet от Наборов палаты общин выглядит многообещающим.
Несколько связанный Сделал Вы Знаете:
существуют полезные методы в java.util.Collections
для перестановки целых наборов: Collections.shuffle(List<?>)
и Collections.shuffle(List<?> list, Random rnd)
.
В шепелявости
(defun pick-random (set)
(nth (random (length set)) set))
В C#
Random random = new Random((int)DateTime.Now.Ticks);
OrderedDictionary od = new OrderedDictionary();
od.Add("abc", 1);
od.Add("def", 2);
od.Add("ghi", 3);
od.Add("jkl", 4);
int randomIndex = random.Next(od.Count);
Console.WriteLine(od[randomIndex]);
// Can access via index or key value:
Console.WriteLine(od[1]);
Console.WriteLine(od["def"]);
Решение JavaScript;)
function choose (set) {
return set[Math.floor(Math.random() * set.length)];
}
var set = [1, 2, 3, 4], rand = choose (set);
Или альтернативно:
Array.prototype.choose = function () {
return this[Math.floor(Math.random() * this.length)];
};
[1, 2, 3, 4].choose();
Так как Вы сказали, что "Решения для других языков также приветствуются", вот версия для Python:
>>> import random
>>> random.choice([1,2,3,4,5,6])
3
>>> random.choice([1,2,3,4,5,6])
4
В Java:
Set<Integer> set = new LinkedHashSet<Integer>(3);
set.add(1);
set.add(2);
set.add(3);
Random rand = new Random(System.currentTimeMillis());
int[] setArray = (int[]) set.toArray();
for (int i = 0; i < 10; ++i) {
System.out.println(setArray[rand.nextInt(set.size())]);
}
Вы не можете только получить размер/длину набора/массива, генерировать случайное число между 0 и размер/длина, затем назвать элемент, индекс которого соответствует тому числу? HashSet имеет .size () метод, я вполне уверен.
В psuedocode -
function randFromSet(target){
var targetLength:uint = target.length()
var randomIndex:uint = random(0,targetLength);
return target[randomIndex];
}
PHP, принимая "набор" является массивом:
$foo = array("alpha", "bravo", "charlie");
$index = array_rand($foo);
$val = $foo[$index];
функции вихря Мерсенна лучше, но нет никакого MT, эквивалентного из array_rand в PHP.
Perl 5
@hash_keys = (keys %hash);
$rand = int(rand(@hash_keys));
print $hash{$hash_keys[$rand]};
Здесь является одним способом сделать это.
Значок имеет тип набора и оператор случайного элемента, унарный"?", таким образом, выражение
? set( [1, 2, 3, 4, 5] )
произведет случайное число между 1 и 5.
случайное семя инициализируется к 0, когда программа запущена, так для приведения к различным результатам на каждом использовании выполнения randomize()
Решение Clojure:
(defn pick-random [set] (let [sq (seq set)] (nth sq (rand-int (count sq)))))
К сожалению, это не может быть сделано эффективно (лучше, чем O(n)) ни в одном из контейнеров стандартных библиотек множеств.
Это странно, так как в хэш-сеты, а также в бинарные множества очень легко добавить функцию рандомизированной пикировки. В не разреженном хэш-сетах вы можете попробовать случайные записи, пока не получите попадание. Для двоичного дерева вы можете выбрать случайный выбор между левым или правым поддеревом, с максимальным количеством шагов O(log2). Я реализовал демоверсию более позднего из приведенных ниже:
import random
class Node:
def __init__(self, object):
self.object = object
self.value = hash(object)
self.size = 1
self.a = self.b = None
class RandomSet:
def __init__(self):
self.top = None
def add(self, object):
""" Add any hashable object to the set.
Notice: In this simple implementation you shouldn't add two
identical items. """
new = Node(object)
if not self.top: self.top = new
else: self._recursiveAdd(self.top, new)
def _recursiveAdd(self, top, new):
top.size += 1
if new.value < top.value:
if not top.a: top.a = new
else: self._recursiveAdd(top.a, new)
else:
if not top.b: top.b = new
else: self._recursiveAdd(top.b, new)
def pickRandom(self):
""" Pick a random item in O(log2) time.
Does a maximum of O(log2) calls to random as well. """
return self._recursivePickRandom(self.top)
def _recursivePickRandom(self, top):
r = random.randrange(top.size)
if r == 0: return top.object
elif top.a and r <= top.a.size: return self._recursivePickRandom(top.a)
return self._recursivePickRandom(top.b)
if __name__ == '__main__':
s = RandomSet()
for i in [5,3,7,1,4,6,9,2,8,0]:
s.add(i)
dists = [0]*10
for i in xrange(10000):
dists[s.pickRandom()] += 1
print dists
Я получил на выходе [995, 975, 971, 995, 1057, 1004, 966, 1052, 984, 1001], так что распределение швов хорошо.
Я боролся с той же самой проблемой для себя, и я еще не решил, что погодные условия, которые дает этот более эффективный подбор, стоят накладных расходов, связанных с использованием коллекции на основе питона. Конечно, я мог бы доработать ее и перевести на С, но сегодня это слишком много для меня :)
.C ++. Это должно быть достаточно быстро, так как не требует повторения по всему набору или его сортировки. Это должно работать из коробки с большинством современных компиляторов, если они поддерживают tr1 . Если нет, возможно, вам придется использовать Boost.
Документы Boost помогут здесь объяснить это, даже если вы не используете Boost.
Уловка состоит в том, чтобы использовать тот факт, что данные были разделены на сегменты, и быстро идентифицировать случайно выбранный сегмент (с соответствующей вероятностью).
//#include <boost/unordered_set.hpp>
//using namespace boost;
#include <tr1/unordered_set>
using namespace std::tr1;
#include <iostream>
#include <stdlib.h>
#include <assert.h>
using namespace std;
int main() {
unordered_set<int> u;
u.max_load_factor(40);
for (int i=0; i<40; i++) {
u.insert(i);
cout << ' ' << i;
}
cout << endl;
cout << "Number of buckets: " << u.bucket_count() << endl;
for(size_t b=0; b<u.bucket_count(); b++)
cout << "Bucket " << b << " has " << u.bucket_size(b) << " elements. " << endl;
for(size_t i=0; i<20; i++) {
size_t x = rand() % u.size();
cout << "we'll quickly get the " << x << "th item in the unordered set. ";
size_t b;
for(b=0; b<u.bucket_count(); b++) {
if(x < u.bucket_size(b)) {
break;
} else
x -= u.bucket_size(b);
}
cout << "it'll be in the " << b << "th bucket at offset " << x << ". ";
unordered_set<int>::const_local_iterator l = u.begin(b);
while(x>0) {
l++;
assert(l!=u.end(b));
x--;
}
cout << "random item is " << *l << ". ";
cout << endl;
}
}