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
- 2322 reads
Dobrii_kot
Sat, 01/16/2021 - 11:01
Permalink
Такая же проблема в PascalABC ABC Паскаль
Среда PascalABC.NET 3.7.1
program check_randomize; type arr = array[1..14] of integer; var first_array,second_array : arr; function initialization_array (x_array : arr): arr; var i,min,max : integer; begin min := -5; max := 20; randomize; for i := low(x_array) to high(x_array) do x_array[i] := min + random(max - min + 1); result := x_array; end; procedure print(z_array : arr); var f : integer; begin for f := low(z_array) to high(z_array) do write('|',z_array[f],'|'); end; begin first_array := initialization_array(first_array); second_array := initialization_array(second_array); print(first_array); writeln(); print(second_array); readln(); end.консоль
Среда Lazarus
type arr = array[1..14] of integer; var min,max : integer; first_array,second_array : arr; function initialization_array (x_array : arr; mn,mx : integer): arr; var i : integer; begin for i := low(x_array) to high(x_array) do x_array[i] := mn + random(mx - mn + 1); result := x_array; end; procedure print(z_array : arr); var f : integer; begin for f := low(z_array) to high(z_array) do write('|',z_array[f],'|'); end; begin min := -5; max := 20; randomize; first_array := initialization_array(first_array,min,max); second_array := initialization_array(second_array,min,max); print(first_array); writeln(); print(second_array); readln(); end.консоль