Одна важная вещь, чтобы знать о генераторах псевдослучайных чисел, состоит в том, что они производят последовательность чисел, а «случайность» - это качество, для которого проверяется последовательность . То есть вы не можете сказать, что конкретное число является случайным или нет ( есть «4» случайное число? ). Вместо этого вы говорите, является ли последовательность чисел случайной или нет.
Когда вы «засеиваете» pRNG, вы обычно выбираете одну из последовательностей, которые она может генерировать, и эти числа являются случайными по отношению к остальной части последовательность. Поэтому, если вы хотите «случайность», вы хотите сначала выбрать определенную последовательность, а затем использовать последовательные числа из этой конкретной случайной последовательности.
В вашем коде без static
вы выбираете последовательность на каждой итерации цикла, а затем используя одно число из этой последовательности. Поскольку вы не используете много значений из одной и той же последовательности, не удивительно, что результат не выглядит случайным.
Когда вы добавляете static
, двигатель больше не высевается на каждой итерации петля. Вместо этого он высевается один раз, и каждая итерация цикла использует последовательные значения из этой последовательности, как и вы должны делать. И это означает, что static
означает переменные с ограниченным блоком: это означает, что переменная живет извне к блоку, в котором он объявлен, и что он будет инициализирован только в первый раз.
static
исправляет ваши проблема, однако я бы сказал, что это нехорошее решение. static
имеют некоторое сходство с глобальными переменными и вызывают некоторые из тех же проблем. Вместо этого я бы рекомендовал вам явно перемещать двигатель за пределы цикла. Например:
int random (int lim, default_random_engine &dre)
{
uniform_int_distribution<> uid(1,lim);
return uid(dre);
}
int main()
{
default_random_engine dre (chrono::steady_clock::now().time_since_epoch().count());
for (int i = 0; i < 10; ++i)
{
cout << random(100, dre) << " ";
}
}
Теперь состояние явно управляется и передается в функцию random()
, что лучше, чем полагаться на скрытое и неявное поведение переменной static
с блочным диапазоном
Также в целом я бы не рекомендовал использовать время как единственный источник данных семян. Часы с низким разрешением могут не обеспечивать новые семена достаточно часто, и программа, выполняемая в разных местах одновременно, может использовать одно и то же семя.
Моя рекомендация для посева:
std::random_device r;
std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()};
std::mt19937 eng(seed);
(Нет необходимости, чтобы новички знали, что такое mt19937 или любой другой бит. Они просто должны знать, чтобы вставить это в соответствующее место и как использовать eng
. В вашем коде вам нужно будет замените каждое использование default_random_engine
на mt19937
.)
Это называют "естественным порядком сортировки". Jeff имел довольно обширная запись в блоге на нем только что, который описывает трудности, Вы могли бы пропустить и имеете ссылки на несколько реализаций.
Существует StrCmpLogicalW, но это - только доступный запуск с Windows XP и только реализованный как Unicode.
Некоторая справочная информация: http://www.siao2.com/2006/10/01/778990.aspx
Путем я понял это, виды Windows Explorer согласно Вашему второму примеру - это всегда раздражало меня чрезвычайно, что упорядочивание выходит 1, 10, 2. Вот почему большинство приложений, которые пишут много файлов (как пакетные приложения) всегда, использует имена файлов фиксированной длины с ведущим 0 или что бы то ни было.
Ваше решение должно работать, но необходимо было бы быть осторожными, где числа были в имени файла, и, вероятно, только используйте подход, если они были в самом конце.
Проводник использует API StrCmpLogicalW () для этого вида сортировки (названный 'естественный порядок сортировки').
Вы не должны писать свою собственную функцию сравнения, просто использовать ту, которая уже существует.
А хорошее объяснение может быть найдено здесь .
Взгляните на телефон
http://www.interact-sw.co.uk/iangblog/2007/12/13/natural-sorting
для некоторого исходного кода.
Я также отправил связанный вопрос с дополнительными подсказками и ловушками:
Сортировка представляет в виде строки, намного более твердо, чем Вы думали