Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   [решено] Случайное перемешивание чисел (http://forum.oszone.net/showthread.php?t=243685)

Любезный 30-09-2012 16:20 1997109

Случайное перемешивание чисел
 
Приветствую уважаемых коллег. Хочу обсудить с вами такой вопрос. В один из своих проектов я недавно добавил такой код:

Код:

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.

VladDV 30-09-2012 16:56 1997126

1) Создаем массив A длиной SettingCount с упорядоченными номерами ячеек: [0, 1, 2, 3,...., SettingCount - 1 ]
2) Создаем пустой массив B длины SettingCount и в цикле заполняем его по след принципу: случайным образом выбираем значение из массива А, вставляем его в текущую ячейку массива B, удаляем использованную ячейку из массива А.

В конце работы программы массив А будет пустым, а В - заполнен перемешанными числами.

На делфи писал лет 7 назад, лень вспоминать синтаксис, но думаю разберетесь.

torauma 01-10-2012 10:49 1997603

Цитата:

Цитата Любезный
Как лучше переписать такой код, чтобы убрать 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;

Вроде так. Проверить не на чем, но вроде должно работать.
По поводу оптимизации смотрите мои комментарии.

Любезный 01-10-2012 19:49 1997905

Цитата:

//Зачем это условие
Блин... Это я сглючил. Конечно, на инициализированных значениях без этой проверки можно обойтись.

Цитата:

Цитата VladDV
удаляем использованную ячейку из массива А. »

Не вижу смысла в использовании двух массивов сразу, тем более с удалением элементов одного массива, которое тоже потребует процессорного времени. Да, команда Move быстра, но когда элементов много, получается замедление.


Время: 10:52.

Время: 10:52.
© OSzone.net 2001-