Problem - wszystkie kombinacje cyrf z rozlacznych zbiorow


(Wasyl3k) #1

mam dosc powazny problem z ktorym nie moge sobie poradzic :confused:

otoz

mam cztery rozlaczne zbiory:

zbior 1. 1 2 3

zbior 2. 4 5

zbior 3. 6 7 8

zbior 4. 9

i musze teraz wygenerowac takie kombinacje cyferek po jednej z kazdego zbioru wyznaczajac wszystkie takie mozliwosci:

kombinacja 1. 1 4 6 9

kombinacja 2. 1 4 7 9

kombinacja 3. 1 4 8 9

kombinacja 4. 1 5 6 9

kombinacja 5. 1 5 7 9

kombinacja 6. 1 5 8 9

kombinacja 7. 2 4 6 9

kombinacja 8. 2 4 7 9

kombinacja 9. 2 4 8 9

kombinacja 10. 2 5 6 9

kombinacja 11. 2 5 7 9

kombinacja 12. 2 5 8 9

kombinacja 13. 3 4 6 9

kombinacja 14. 3 4 7 9

kombinacja 15. 3 4 8 9

kombinacja 16. 3 5 6 9

kombinacja 17. 3 5 7 9

kombinacja 18. 3 5 8 9

wypisujac je recznie nie ma wiekszego problemu ale nie moge sobie poradzic z tym jak to zaimplementowac aby program automatycznie generowal mi te kombinacje

DODAM TYLKO ZE TO TYLKO PRZYKLAD BO ZBIORY ROZLACZNE BEDA SIE ZMIENIAC WIEC POTRZEBUJE SPOSOBU UNIWERSALNEGO

jesli mozecie mi dac jakies wskazowki albo cos w pseudokodzie lub jeszcze lepiej jakis przyklad w Delphi/Pascal

z gory dzieki za kazda pomoc i pozdrawiam

wasyl3k


(Wasyl3k) #2

utworzylem 4 tablice i je z palca uzupelnilem i zadzialalo tak jak chcialem:

t1,t2,t3,t4 : array[0..2] of integer;

  i,k,l,j,kombinacja : integer;


begin

kombinacja :=0;

t1[0] := 1;

t1[1] := 2;

t1[2] := 3;

t2[0] := 4;

t2[1] := 5;

t2[2] := 0;

t3[0] := 6;

t3[1] := 7;

t3[2] := 8;

t4[0] := 9;

t4[1] := 0;

t4[2] := 0;


for i := 0 to high(t1) do

 begin

  if (t1[i] = 0) then break

   else begin

    for j := 0 to high(t2) do

     begin

      if (t2[j] = 0) then break

       else begin

        for k := 0 to high(t3) do

         begin

          if (t3[k] = 0) then break

           else begin

            for l := 0 to high(t4) do

             begin

              if (t4[l] = 0) then break

               else begin

                inc( kombinacja );

                Memo1.Lines.Add( IntToStr(kombinacja) + ': ' + IntToStr(t1[i]) + ' ' + IntToStr(t2[j]) + ' ' + IntToStr(t3[k]) + ' ' + IntToStr(t4[l]));

               end;

             end;

           end;

         end;

       end;

     end;

   end;

 end;

ale chodzi o to ze ja nie moge tego na pojedynczych tablicach zrobic bo nie wiem ile ich bedzie bo liczba zbiorow generuje mi sie w programie wiec nie moge zalozyc ze to bede 4 petle bo moze ich byc np 2 albo 102 ;/ a raczej dynamicznie kodu nie moge tworzyc

wiec wraca problem jednej zbiorczej tablicy ktora wyglada tak:

1 2 3 0 0 0

4 5 0 0 0 0

6 7 8 0 0 0

9 0 0 0 0 0

czy ma ktos jakis pomysl jak zrobic podobny algorytm dla takiej tablicy ? (ilosc zer nie ma znaczenia bo i tak sa pomijane jako puste miejsce w tablicy)


(system) #3
var T:array of array of Integer;

var P:array of Integer;

var I,K:Integer;

var S:String;

begin

  // Wypełniasz tablice T

  SetLength(T,4);

  SetLength(T[0],3); T[0][0]:=1; T[0][1]:=2; T[0][2]:=3;

  SetLength(T[1],2); T[1][0]:=4; T[1][1]:=5;

  SetLength(T[2],3); T[2][0]:=6; T[2][1]:=7; T[2][2]:=8;

  SetLength(T[3],1); T[3][0]:=9;


  // Algorytm

  SetLength(P,Length(T)); // Jeden element na ka┼╝d─ů tablic─Ö

  for I:=0 to Length(P)-1 do P[I]:=0; // indeksy na 0 == pierwszy element z ka┼╝dej tablicy

  while true do

  begin

    // Notujesz kolejny wynik, tu do napisu S

    SetLength(S,0); for I:=0 to Length(P)-1 do S:=S+IntToStr(T[I][P[I]])+','; SetLength(S,Length(S)-1);

    Memo1.Lines.Add(S);


    K:=Length(P)-1; // Zaczynamy od ostatniej tablicy

    while K>=0 do // dop├│ki mamy jakie┼Ť tablicy

    begin

      Inc(P[K]); // przestawiamy indeks na nast─Öpny

      if P[K]
      P[K]:=0; // je┼╝eli za┼Ť przekroczy┼é to przestawiamy na pierwszy indeks

      Dec(K); // i bierzemy w obroty poprzedni─ů tablic─Ö

    end;

    if K<0 then Break; // je┼╝eli wszystkie tablice przeskoczyli przez zakres to koniec kombinacji

  end;

end;