|
|
Случайное перемешивание чисел
Приветствую уважаемых коллег. Хочу обсудить с вами такой вопрос. В один из своих проектов я недавно добавил такой код:
Код:
const SettingCount = 15;
var SortedSettingNumbers: array [0..SettingCount-1] of smallint;
i, j, r: smallint;
label lab1;
...
for I:=0 to SettingCount-1 do SortedSettingNumbers [i]:=-1;
Randomize;
for I:=0 to SettingCount-1
do if SortedSettingNumbers [i]=-1
then begin
lab1: r:=Random (SettingCount);
// проверить сгенерированное число на повтор
b:=false;
for j:=0 to SettingCount-1
do if SortedSettingNumbers [j]=r
then begin
b:=true;
break;
end;
// если повторяется - сгенерить другое
if b then goto lab1;
SortedSettingNumbers [i]:=r
end;
Задача этого кода - заполнить массив SortedSettingNumbers случайными числами в диапазоне от 0 до SettingCount-1 таким образом, чтобы числа не повторялись, т.е. по сути дела получить в массиве перемешанную последовательность чисел.
Есть два вопроса:
а) Как лучше переписать такой код, чтобы убрать goto, которое многие программисты не любят? Мне в голову это никак не придёт.
б) Хотелось бы также услышать предложения по ускорению этого кода, так как в будущем, возможно, придётся сильно увеличить константу SettingCount.
|
1) Создаем массив A длиной SettingCount с упорядоченными номерами ячеек: [0, 1, 2, 3,...., SettingCount - 1 ]
2) Создаем пустой массив B длины SettingCount и в цикле заполняем его по след принципу: случайным образом выбираем значение из массива А, вставляем его в текущую ячейку массива B, удаляем использованную ячейку из массива А.
В конце работы программы массив А будет пустым, а В - заполнен перемешанными числами.
На делфи писал лет 7 назад, лень вспоминать синтаксис, но думаю разберетесь.
|
Цитата:
Цитата Любезный
Как лучше переписать такой код, чтобы убрать goto, »
|
Код:
const SettingCount = 15;
var SortedSettingNumbers: array [0..SettingCount-1] of smallint;
i, j, r: smallint;
label lab1;
...
for I:=0 to SettingCount-1 do SortedSettingNumbers [i]:=-1; //Инициализация значений элементов массива? А нужно ли?
Randomize;
for I:=0 to SettingCount-1
do if SortedSettingNumbers [i]=-1 //Зачем это условие
then begin
b:=true;
repeat
begin
r:=Random (SettingCount);
// проверить сгенерированное число на повтор
for j:=0 to SettingCount-1
do if SortedSettingNumbers [j]=r
then begin
b:=false;
break;
end;
end;
until b;
// если повторяется - сгенерить другое
SortedSettingNumbers [i]:=r;
end;
Вроде так. Проверить не на чем, но вроде должно работать.
По поводу оптимизации смотрите мои комментарии.
|
Блин... Это я сглючил. Конечно, на инициализированных значениях без этой проверки можно обойтись.
Цитата:
Цитата VladDV
удаляем использованную ячейку из массива А. »
|
Не вижу смысла в использовании двух массивов сразу, тем более с удалением элементов одного массива, которое тоже потребует процессорного времени. Да, команда Move быстра, но когда элементов много, получается замедление.
|
Время: 10:52.
© OSzone.net 2001-