pascal random() для randomize() вызванного Внутри процедуры возвращает одно и то же значение
Primary tabs
Судя по всему это происходит из-за слишком быстрого срабатывания кода, так что не успевает смениться системное время на которое опирается randomize().
Пример проблемного кода (проверяли в Lazarus 2.0,10 в т.ч. в Ubuntu LInux):
program z17; type // секция объявления типов myArr = array [1..20] of integer; var a1, a2: myArr; //array [1..20] of integer; i: integer; procedure init(var a: myArr); var min, max, x: integer; begin randomize(); min := -10; max := 10; for i:=low(a) to high(a) do begin x := min + random(max - min + 1); a[i] := x; writeln('x=', x); end; writeln(); writeln(); end; procedure print(a: myArr); begin for i:=low(a) to high(a) do write(a[i], ' '); writeln(); end; begin init(a1); init(a2); writeln('First array:'); print(a1); writeln(); writeln('Second array:'); print(a2); writeln(); readln(); end.
НО: если выполнять этот код пошагово в отладчике - все будет как и ожидалось, так как выполнение построчно значительно медленнее, чем обычное выполнение и между двумя вызовами randomize() успевает пройти время.
Демонстрация проблемы с задержкой выполнения
Используя Sleep() мы сожем задержать выполнение программы:
program z17; //uses Crt; uses sysutils; type // секция объявления типов myArr = array [1..100] of integer; var a1, a2: myArr; i: integer; procedure init(var a: myArr); var min, max, x: integer; begin randomize(); min := -10; max := 10; for i:=low(a) to high(a) do begin x := min + random(max - min + 1); a[i] := x; //writeln('x=', x); end; writeln(); writeln(); end; function ravniLiMassivi(a1, a2: myArr): boolean; var helper: boolean; begin helper := true; for i:=low(a1) to high(a1) do if (a1[i] <> a2[i]) then helper := false; result := helper; end; begin init(a1); Sleep(800); // можно подобрать минимальное число // миллисекунд, при котором массивы будут не равны init(a2); if (ravniLiMassivi(a1, a2) = true) then writeln('ravni') else writeln('Ne ravni'); writeln('First array:'); writeln(); //readln(); end.
-- получается что randomize переиниацилизирует генератор случайных чисел, в случае если между вызовами randomize проходит время не меньшее, чем где-то 1 секунда.
Недежное решение
Вызывайте randomize() один раз, при генерации последовательности массивов, напр. заранее в теле программы.
- Log in to post comments
- 1702 reads
Dobrii_kot
Sat, 01/16/2021 - 11:01
Permalink
Такая же проблема в PascalABC ABC Паскаль
Среда PascalABC.NET 3.7.1
консоль
Среда Lazarus
консоль