Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

список из случайных неповторяющихся чисел


bag ©   (2009-08-02 17:23:00) 

Поставил задачу, получить список из случайных не повторяющихся чисел.
Вот что получилось, вроде работает, но один раз из 10-15 получается список с двумя одинаковыми четверками, что за бред не пойму. Помогите плиз разобраться!
var
 i, ran1, ran2: integer;
 bo: Boolean;
 list: TStringList;
begin
 list := TStringList.Create;
 Randomize;

   list.Clear;
   for i := 0 to 3 do
   begin
     ran2 := Random(12) + 1;
     bo := false;
     if list.IndexOf(IntToStr(ran2)) = -1 then
       list.Add(IntToStr(ran2))
     else begin
       repeat
         ran1 := Random(12) + 1;
         bo := true;
       until (list.IndexOf(IntToStr(ran1)) = -1);
       if bo then
         list.Add(IntToStr(ran1));
     end;
   end;
   lst2.Clear;
   SortList(list);
   lst2.Items.AddStrings(list);
   list.Free;


Leonid Troyanovsky   (2009-08-03 12:46:00) [1]


> bag   (02.08.09 17:59) [5]

> мне надо получить 4 случайных числа, random(12)


function RandEx(const a, b: Longint; const excludes: array of Longint):Longint;
var
 i, m : Longint;
begin
 m := High(excludes);
 Assert(m >= 0, 'Invalid param: excludes');
 Result := a + Random(b-a-m);
 for i := 0 to m do
   if (Result >= excludes[i]) then
     inc(Result)
   else
     Break;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 e: array [0..3] of Longint;
 cnt, i, j, v : Longint;
begin
 e[0] := 1 + Random(12);
 cnt := 1;
 for i := 1 to 3 do
   begin
     e[i] := RandEx(1, 12, Slice(e, cnt));
     for j := cnt downto 1 do
       begin
         if (e[j] < e[j-1]) then
           begin
             v := e[j];
             e[j] := e[j-1];
             e[j-1] := v;
           end;
       end;
     inc(cnt);
   end;
   for j := 0 to cnt-1 do
     with StringGrid1 do
       Cells[0, e[j]] := IntToStr(StrToInt(Cells[0, e[j]])+1);
end;

--
Regards, LVT.


Сергей М.   (2009-08-02 19:48:00) [2]


> Юрий Зотов ©   (02.08.09 19:42) [14]


Тоже верно, спору нет)


Юрий Зотов   (2009-08-02 19:42:00) [3]

> Сергей М. ©   (02.08.09 19:06) [12]

И хорошо. Заодно и узнает, что такое Set...
:o)


Сергей М.   (2009-08-02 19:07:00) [4]


> Anatoly Podgoretsky, за часто ненужные комметарии


Но здесь, кстати и к счастью, оч даже уместные


Сергей М.   (2009-08-02 19:06:00) [5]


> Юрий Зотов ©   (02.08.09 18:50) [9]


А завтра автор развернет оглобли и захочет получить, скажем, всечисла в рандомной последовательности из диапазона set of Word.. или set of DWord ..


bag   (2009-08-02 19:05:00) [6]

Юрий Зотов, спасибо!
Спасибо и тебе Anatoly Podgoretsky, за часто ненужные комметарии:)))


Anatoly Podgoretsky   (2009-08-02 18:56:00) [7]

> bag  (02.08.2009 18:27:07)  [7]

Вряд ли, вопрос просто обсосан до костей, какой уж интерес.


Юрий Зотов   (2009-08-02 18:50:00) [8]

Чет как-то слишком наворочено для такой простой задачки...

var
 Numbers: set of byte = [];

procedure TForm1.FormCreate(Sender: TObject);
var
 Count: integer;
 N: byte;
begin
 Randomize;
 Count := 1;
 while Count < 5 do
 begin
   N := Random(12);
   while N in Numbers do
     N := Random(12);
   Include(Numbers, N);
   Inc(Count)
 end
end;


Сергей М.   (2009-08-02 18:29:00) [9]


> bag   (02.08.09 18:27) [7]


Не за что.
Посто заготовка под рукой оказалась.


bag   (2009-08-02 18:27:00) [10]

Сергей М, огромное человеческое спасибо, очень помогли мне! вижу что вам это самому интересно было:)


Сергей М.   (2009-08-02 18:09:00) [11]


> надо получить 4 случайных числа, random(12)



procedure TForm1.Button4Click(Sender: TObject);
var
 Ranges: TList;
 NumCount, NextNumber, MinNumber, MaxNumber, RngFrom, RngTo: Word;
 CurRange: DWord;
 ri: Integer;
begin
 Ranges := TList.Create;
 MinNumber := 0;
 MaxNumber := 11;
 NumCount := 4;
 Ranges.Add(Pointer(MakeLong(MinNumber, MaxNumber)));
 Randomize;
 while (NumCount > 0) and (Ranges.Count > 0) do begin
   ri := Random(Ranges.Count);
   CurRange := DWord(Ranges[ri]);
   RngFrom := LoWord(CurRange);
   RngTo := HiWord(CurRange);
   NextNumber := Random(RngTo - RngFrom) + RngFrom;
   if (NextNumber > RngFrom) and (NextNumber < RngTo) then begin
     Ranges[ri] := Pointer(MakeLong(RngFrom, Pred(NextNumber)));
     Ranges.Add(Pointer(MakeLong(Succ(NextNumber), RngTo)));
   end else if (NextNumber = RngFrom) and (NextNumber = RngTo) then
     Ranges.Delete(ri)
   else if (NextNumber = RngFrom) then
     Ranges[ri] := Pointer(MakeLong(Succ(RngFrom), RngTo))
   else if (NextNumber = RngTo) then
     Ranges[ri] := Pointer(MakeLong(RngFrom, Pred(RngTo)));
   Memo.Lines.Add(IntToStr(NextNumber));
   Dec(NumCount);
 end;
end;


bag   (2009-08-02 17:59:00) [12]

мне надо получить 4 случайных числа, random(12)


bag   (2009-08-02 17:44:00) [13]

ничего не понял :(
начиная с создания списка используемых значений


Palladin   (2009-08-02 17:38:00) [14]

подход прост, создать список используемых значений и вытаскивать из него по рандомным индексам и тут же удалять.


bag   (2009-08-02 17:35:00) [15]

это, да лишнее, привиденный кусок кода я вытащил из большего


Palladin   (2009-08-02 17:33:00) [16]


>    list.Clear;

Зачем?


Наверх

Титульная страница Поиск, карта сайта Написать письмо