Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: wszystkie mozliwe kombinacje
Forum PHP.pl > Forum > PHP
deniol13
witam, poszukuje skryptu/algorytmu ktory z jakiejs tablicy ktora zawiera integery wszystkie kombinacje bez powtorzen
np

$tab[a] = 1;
$tab[b] = 2;
$tab[c] = 3;

wszystkie kombinacje to
123
213
321
312
231
i moze jeszcze pare
paxton
10 sekund szukania w google
  1. <?php
  2. header('Content-Type: text/plain');
  3.  
  4. function showCombinations($string, $traits, $i)
  5. {
  6. if ($i >= count($traits))
  7. echo trim($string) . "\n";
  8. else
  9. {
  10. foreach ($traits[$i] as $trait)
  11. showCombinations("$string $trait", $traits, $i + 1);
  12. }
  13. }
  14.  
  15. $traits = array
  16. (
  17. array(1, 2, 3, 4),
  18. array(1, 2, 3, 4),
  19. array(1, 2, 3, 4)
  20. );
  21.  
  22. showCombinations('', $traits, 0);
  23. ?>

thek
Set... Mój post jaki linkujesz tyczy wariacji z powtórzeniami. Nie kombinacji z powtórzeniami. A patrząc co chce autor to ma to być wariacja, ale bez powtórzeń (ważna kolejność, nie może się powtarzać element). Jak najprościej zrobić ją? Algorytm:
1. Weź tablicę liczb i usuń duplikaty ( no chyba, że może być kilka wystąpień tej samej liczby, ale wątpię, bo to spowoduje wystąpienie duplikatów w wyniku! )
2. W pętli przesuwaj się po wszystkich elementach tablicy
3. Zastosuj (ilość_elementów-2) takich pętli pomniejszonych o element pętli wyższego rzędu. Jak to miałoby wyglądać?
tablica = (2,4,7,9)
Pętla_1 (2,4,7,9)
Bierzesz 2, Pętla_2 (4,7,9)
Bierzesz 4, Pętla_3 (7,9)
Z tego dostaniesz liczby 2,4,7,9 i 2,4,9,7
Zmienia się Pętla_2, która wskazuje teraz nie na 4, ale 7. Pętla_3 też się zmienia! Zawiera bowiem (4,9)
Mamy więc 2,7,4,9 i 2,7,9,4
Znowu zmiana w Petla_2 z 7 na 9 i po raz kolejny Pętla_3 zmiany uwidacznia (4,7)
Mamy 2,9,4,7 i 2,9,7,4
Zarówno Pętla 2 i 3 doszły do ostatnich elementów, więc zmiana w Pętla_1, z 2 na 4. Lec tak dalej a sam zauważysz jak to ma działać winksmiley.jpg Podpowiem... znów zagnieżdżone rekurencyjnie foreach smile.gif
cojack
Co Wy nawet do wzoru nie potraficie podstawić liczb?

  1.  
  2. function silnia( $x) {
  3. if( $x == 0 )
  4. return 1;
  5. return $x * silnia( $x - 1 );
  6. };
  7.  
  8. $n = 3; // czyli mamy 1,2 i 3
  9. $k = 3; // kombinacja 3 cyfr
  10.  
  11. $wynik = ( (silnia( $n ) / silnia( $n - $k ) );


takie trudne?
Crozin
Cytat
Co Wy nawet do wzoru nie potraficie podstawić liczb?
Eee.. a wiesz jaka jest różnica pomiędzy obliczeniem ilości tych wariacji, a wygenerowaniem ich?
cojack
Nie ma.


@EDIT a jednak jest ;D
celbarowicz
człowieku, to nie są kombinacje, to są permutacje.
thek
To ja po kilku postach naszkicuję szybko algorytm:
1. Weź tablicę i usuń duplikaty.
2. Jeśli tablica ma jakieś elementy weź ją i ustaw ją do przechodzenia w pętli
3. Jeśli tablica ma 1 element wyświetl elementy ze znajdujących się "wyżej" pętli i ten element oraz wróć do pętli wyższego rzędu i przesuń licznik na kolejny element
3. Jeśli ma więcej elementów, tablicę pomniejsz o wybrany element
4. Pomniejszona tablica jest pętlą kolejnego rzędu, czyli wracamy do kroku 2.

Można to optymalizować jak ja zasugerowałem, czyli gdy tablica ma już tylko 2 elementy, to wyświetlamy wszystkie wcześniejsze a owe dwa elementy tylko zamieniamy miejscami w wynikach. Z jednej rekurencji wtedy spadamy dodając 2 wyniki w tym przebiegu.
celbarowicz
szkic niezbyt ambitnego sposobu wypisywania wszystkich permutacji zbioru np:{a,b,c,d,e,...}

w tablicy t1 umieszczamy w t1[1] element a , t1[1]=a
pobieramy następny element ->b , i w nowej tablicy t2 wpisujemy w t2[1] łańcuch ba czyli: t2[1] = ba
a w t2[2] łańcuch ab czyli: t2[2] = ab
---------------------------------------------------------------------------------------------------------------------------------
teraz manewry łańcuchem na elemencie t2[1] = ba pobieramy element c w wpisujemy do tablicy t1

t1[1]=cba
t1[2]=bca
t1[3]=bac
podobnie robimy to z t2[2] = ab t1[4]=cab
t1[5]=acb
t1[6]=abc
--------------------------------------------------------------------------------------------------------------------
wykorzystując poprzednie dane z tablicy t1 i pobierając następny element d mamy:
(teraz dane wprowadzamy ponownie do tablicy t2)
t1[1]=cba daje nam t2[1]=dcba
t2[2]=cdba
t2[3]=cbda
t2[4]=cbad
--------------------------------------------------------------------------------------------------------
t1[2]=bca daje nam t2[5]=dbca
t2[6]=bdca
t2[7]=bcda
t2[8]=bcad
--------------------------------------------------------------------------------------------------------
itd dla t1[3] ,...,t1[6]

=================================================================
przy pobraniu następnego elementu ->e dane będą wpisywane do tablicy t1 a wydłużane będą łańcuchy tablicy t2

pozdrawiam.






Fifi209
Masz tutaj dwie metody:

  1. <?php
  2.  
  3. function silnia($x) {
  4. if ($x == 0) {
  5. return 1;
  6. }elseif ($x > 0) {
  7. for ($i=1,$y=1; $i <= $x; $i++) {
  8. $y *= $i;
  9. }
  10. return $y;
  11. }else{
  12. return 0;
  13. }
  14. }
  15.  
  16. function permutation($array) {
  17. $x = array();
  18. $l = silnia(count($array));
  19.  
  20. while (count($x) != $l) {
  21. $temp = implode('', $array);
  22. $temp = str_shuffle($temp);
  23. if (!in_array($temp, $x)) {
  24. $x[] = $temp;
  25. }
  26. }
  27.  
  28. return $x;
  29. }
  30.  
  31. function permutation_r($array) {
  32. static $temp = array();
  33. if (count($temp) != silnia(count($array))) {
  34. $x = implode('', $array);
  35. $x = str_shuffle($x);
  36. if (!in_array($x,$temp)) {
  37. $temp[] = $x;
  38. }
  39. unset($x);
  40. return permutation_r($array);
  41. }else{
  42. return $temp;
  43. }
  44. }
  45.  
  46. echo '<pre>';
  47. $t = permutation(array('a','b','c','d','e','f'));
  48. print_r($t);
  49.  
  50. ?>
  51.  


Jednak z góry piszę, że nie są one optymalne.
permutation będzie działało najprawdopodobniej szybciej od permutation_r - albo przynajmniej mniej pamięci zje.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.