FAQ » Algorytmy

Jak wylosować tablicę z niepowtarzającymi się liczbami

  • 2012-02-05 18:59
  • 12 komentarzy
  • 1830 odsłon
  • Oceń ten tekst jako pierwszy
Właśnie potrzebowałem mieć tablicę, w której elementy się nie powtarzają. Pokombinowałem, poszukałem na forum i oto przedstawiam moje wypociny ;)

Do rzeczy:

Gdzieś na początku musimy zdefiniować taki typ

const
  N : Integer;  // ilość elementów w tablicy
 
type 
  TTab = array [0..N - 1] of byte;


Następnie wpisujemy funkcję:

function FillArrayWithRandomNumbers(): TTab;
var I, A, B : Byte;
    TabStr  : TStringList;
    J       : Integer;  // Zmienna pomocnicza
begin
  J := 0;
  Randomize;
  TabStr := TStringList.Create;
 
  for I := 0 to (N-1) do
    TabStr.Add(InTtoStr(I));  // Najpierw tablica pomocnicza wypełniana jest liczbami po kolei
 
  repeat
    A := Random(N);
    B := Random(N);
    Tabstr.Move(A, B);  // następnie "mieszane" są elementy
    Inc(J);
  until J > 100000;
 
  for I := 0 to (N-1) do
    Result[I] := StrToInt(TabStr[I]);  // a wynik przepisywany jest do właściwej tablicy
 
  TabStr.Free;
end;


Potem, jesli potrzebujemy takiej tablicy to dajemy po prostu:

var 
  TablicaBezPowtorzen: TTab;
 
///...
 
  TablicaBezPowtorzen := FillArrayWithRandomNumbers;

12 komentarzy

adam85 2006-10-18 20:19

Możecie napisać podobny program, ale żeby losował 5losowy wybranych kart z całej tali (52karty) - zeby rozrózniał kolory. Czyli wybierał losowe 5elementów z dwuwymiarowej tablicy?

adam85 2006-10-18 20:08

witam,
a możecie napisać wybór 5kart z całej tali? np do pokera ? Jak wybrać losowy element z tablicy dwuwymiarowej ?

msuszczynski 2006-05-10 23:27

a ja przedstawiam moje wypociny, pozostaje kwestia tablicy ale uwazam ze to kazdy potrafi zrobic.

program Project2;
{$APPTYPE CONSOLE}
uses
  SysUtils;

type
  Tkula = 1..80; //typ Tkula będzie potrzebny do zdefiniowania zbioru kul
var
  pula : set of Tkula; // zbiór kul notabene zmiennych tpyu Tkula
  i : integer; // iterator pętli, będzie wskazywał na nr losowania pewnej kuli
  liczba : Tkula; // zmienna liczba będzie przechowywać nr aktualnie wylosowanej kuli
label G;
begin
  pula := [1..80]; //definiujemy nasz zbior kul
  Writeln('Program losuje 20 liczb z 80, tzw. Multilotek');
  Randomize; // uruchamiamy generator liczb pseudolosowych
  //-----------losowanie-------------------------
  Writeln('Wylosowano następujące kule: ');
  for i := 1 to 20 do // chcemy wylosować 20 kul
  begin
    G: //etykieta skoku
    liczba := Random(80); //losujemy liczby z przedzialu 1..80, wiec  ew. 0 odpadnie w nastepujacej instrukcji warunkowej
    if (liczba in pula) and then Write(liczba,' ') else goto G; //sprawdzamy czy dana liczba jest w puli, jesli tak oznacza ze jest unikalna i wypisujemy na ekran, jesli nie losujemy jeszcze raz - ponowne losowanie moze takze znaczyc ze wylosowalismy wspomniane wczesniej 0
    Exclude(pula,liczba); //wyrzucamy wylosowana liczbe z puli
  end;
  Readln; //to wszystko
end.

_13th_Dragon 2005-08-01 17:03

Podane warianty sa czasochlonne i nie daja liniowego rozkladu.
Czy nie proszcej zrobic cos takiego. Szybko i rozklad liniowy:

procedure Generator(var Tb:TIntegerArray;MinValue,Count:Integer);
var I,P:Integer;
var Tmp:Integer;
begin
  SetLength(Tb,Count);
  for I:=0 to Count-1 do Tb[I]:=MinValue+I;
  for I:=Count-1 downto 1 do
  begin
    P:=Random(I+1);
    if P<>I then
    begin
      Tmp:=Tb[I];
      Tb[I]:=Tb[P];
      Tb[P]:=Tmp;
    end;
  end;
end;

Adamo 2004-10-03 21:27

no bo z varu przeprawił na const i wyszło pół z tego i pół z tego, wstaw se tam tą liczbę ile elementów ma być w tablicy :)

brodny 2004-09-29 20:12

Ciąg dalszy - niby jest to stała, ale jaką ona ma wartość??? (chodzi mi o stałą n)

brodny 2004-12-02 16:09

Hmmm, ja to wiem, ale co, jak ktoś nie będzie wiedział? Będzie miał problem i napisze o tym na forum zapewne...

mi 2004-09-08 21:11

To moja pierwsza wskazówka, prosze wszelkie autorytet oraz szanownych użytkowników o słowo komentarza. Pozdrawiam mi.

brodny 2004-09-08 21:49

O ile się nie mylę, to ogranicznikiem tablic w Pascalu nie może być zmienna.

mi 2004-09-08 22:12

łojoj, racja, literówka ;) Dzięki, za szybką reakcję już poprawiłem.

Adamo 2004-09-08 22:14

a ta procka powyżej to albo mi się wydaje albo będzie troche wolna, zwłaszcza będzie to widoczne jak się weźmie ze 20 razy pod rząd ją wywoła, ale oki

a moja procka do losowania liczb 20 z 80 bez powtarzania się (multilotek) wygląda tak (tak przy okazji :) - tak se skopiowałem z programiku mojego jednego bo nie miałem co robić):

<quote>

var wyniki:array[1..20] of byte; {tablica 20 elementowa bo tyle chce wylosować liczb} i,j,liczba:byte;
 dawaj:boolean;
begin
 for i:=1 to 20 do begin // losujemy 20 liczb
  dawaj:=false;
  while not dawaj do begin
   dawaj:=true;
   liczba:=random(80)+1; // losujemy liczbę od 1 do 80
   if i>1 then
    for j:=1 to i-1 do if wyniki[j]=liczba then dawaj:=false; // spr. czy liczby nie było wcześniej wylosowanej
  end;
  wyniki[i]:=liczba; // jeśli nie było to przypisujemy
 end;
 Edit1.Text:=IntToStr(wyniki[1]); // pierwsza liczba bez przecinka na początku
 for i:=2 to 20 do Edit1.Text:=Edit1.Text+', '+IntToStr(wyniki[i]); // pozostałe liczby oddzielone przecinkiem
end;
</quote>