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

mi

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

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?

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

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.

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;

niepowtarzający się już jest sam czas.. nie załapałem czy chodzi tu o jakąś tablicę wypełniąną "n" ilością różnych cyfr, czy tylko jedną cyfrę nigdy się niepowtarzającą się .. na oba rozwiązania mam prostszy sposób.. jeśli są pytania proszę na maila tu@epf.pl

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 :)

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

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

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

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

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

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ć):

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;