Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Как можно перемешать элементы одномерн. массива?


Автор: hedge_hog 22.6.2007, 00:19
Здравствуйте. Знает ли кто есть ли процедура или функция которая переставляет в хаотичном порядке элементы массиа. Или самому нужно алгоритм соченять.

Автор: Alexeis 22.6.2007, 09:38
Не слышал про такое. Думаю просто Random() и в цикле переставлять.

Добавлено через 1 минуту и 25 секунд
Лучше даже пройтись по всем индексам от 1го до последнего, а рэндомом генерить индекс элемента с которым нужно будет обменять текущим. Т.о. поменяют позицию все элементы.

Автор: Rennigth 22.6.2007, 10:06
Цитата(Alexeis @  22.6.2007,  09:38 Найти цитируемый пост)
Лучше даже пройтись по всем индексам от 1го до последнего, а рэндомом генерить индекс элемента с которым нужно будет обменять текущим. Т.о. поменяют позицию все элементы. 


согласен, сам такое юзал, хотя может и можно придумать что-нибудь более оригинальное.
Код

procedure ShuffleDynIntArray(var VDynArray: TDynIntegerArray);
var
  i, lTmp: Integer;
  lItem: Integer;
begin
  for i := Low(VDynArray) to High(VDynArray) do
  begin
    lTmp := Random(High(VDynArray));
    lItem := VDynArray[lTmp];
    VDynArray[lTmp] := VDynArray[i];
    VDynArray[i] := lItem;
  end;
end;



Автор: hedge_hog 22.6.2007, 10:21
Alexeis, Rennigth, Огромное СпасиБо.

Автор: Alexeis 22.6.2007, 10:26
Rennigth, раз  for i := Low(VDynArray)  тогда уже 
Код

procedure ShuffleDynIntArray(var VDynArray: TDynIntegerArray);
var
  i, lTmp: Integer;
  lItem: Integer;
begin
  for i := Low(VDynArray) to High(VDynArray) do
  begin
    lTmp := Low(VDynArray) + Random(High(VDynArray) - Low(VDynArray) + 1);
    lItem := VDynArray[lTmp];
    VDynArray[lTmp] := VDynArray[i];
    VDynArray[i] := lItem;
  end;
end;

Автор: Rennigth 22.6.2007, 10:55
Alexeis, а зачем +1? Вылетишь же за пределы массива...

Добавлено через 11 минут и 43 секунды
Alexeis, забыл что Random 
Цитата

0 <= X < Range

:(

Тогда так: 
Код

procedure ShuffleDynIntArray(var VDynArray: TDynArrayInteger);
var
  i, lTmp: Integer;
  lItem: Integer;
begin
  for i := Low(VDynArray) to High(VDynArray) do
  begin
    lTmp := Random(High(VDynArray) + 1);
    lItem := VDynArray[lTmp];
    VDynArray[lTmp] := VDynArray[i];
    VDynArray[i] := lItem;
  end;
end;


Зачем лишние вычисления Low?

Автор: Alexeis 22.6.2007, 11:48
Цитата(Rennigth @  22.6.2007,  10:55 Найти цитируемый пост)
Зачем лишние вычисления Low? 

Вот именно! И я об этом smile зачем нужно
Код

   for i := Low(VDynArray) to ...

?
когда все динамические массивы и открытые начинаются с "0". Получается непоследовательно, раз используется  Low(VDynArray), значит начало может быть не нулем, а раз начало не ноль, то Random легко может вернуть ноль, что будет за пределами массива и вызовет ошибку. 

Автор: Rennigth 22.6.2007, 12:29
Просто считаю хорошей привычкой использовать и для дин.массивов и для стат.массивов использование одной конструкции Low/High. Хоть и пишут:
Цитата

Dynamic arrays are always integer-indexed, always starting from 0.

Но вот так мне кажется менее наглядно:
Код

for i := 0 to High(VDynArray) do

Просрачность кода увеличивается. Хотя каждому свое.

Автор: Alexeis 22.6.2007, 13:02
Цитата(Rennigth @  22.6.2007,  12:29 Найти цитируемый пост)
Просто считаю хорошей привычкой использовать и для дин.массивов и для стат.массивов использование одной конструкции Low/High. Хоть и пишут:

  Вооот, очень хорошо, тогда почему же в 
Код

lTmp := Random(High(VDynArray) + 1);
    lItem := VDynArray[lTmp];
    VDynArray[lTmp] := VDynArray[i];
    VDynArray[i] := lItem;


индексы массивов неожиданно начали начинаться с нуля, раз предполагается безболезненно переносить на статические? Будешь помнить, что делал универсальную функцию, откопипастишь, а оно начнет глючить и писать в чужую память.

Либо универсально, либо уникально. Уникально-универсальные процедуры главный кандидат на трудноуловимые ошибки. Вроде уверен, что все делал универсально, а не работает  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)