Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: wszystkie kombinacje literowocyfrowe
Forum PHP.pl > Forum > PHP
Deen
Witam.
Potrzebuję skryptu którego działania podam poniżej:)
Skrypt najprosciej w swiecie ma wypisac wszystkie kombinacje literowe.
Wiem jak wypisac cyfry.
Czy mógł by mi ktoś podać skrypt który wypisze wszystkie 3literowocyfrowe kombinacje?smile.gif

000 001 002 AAB itd
ważne żeby było pokolei i żeby mógł większyć z np 3 liter na 4 lub 5....
Mam nadzieję, że mi pomożecie:)
Wicepsik
  1. $ar1=array('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z');
  2. for($i=0; $i<=1; $i++)
  3. {
  4. for($j=$i;$j<count($ar1);$j++)
  5. {
  6. for($k=$j;$k<count($ar1);$k++)
  7. {
  8. print "<br>".$ar1[$i].$ar1[$j].$ar1[$k];
  9. }
  10. }
  11. }
celbarowicz
pomysł bardzo dobry(ale na końcy?questionmark.gif i w środku questionmark.gif? nie tworzy kombinacji) , count począwszy od pierwszego for należy skracać stopniowo o 1 zaczynając np od 5,4,3... w miarę zagłębiania się w pętli

przykład dla kombinacji 3 elementowych:
  1. <?php
  2.  
  3. $link=mysql_connect('localhost','root','');
  4. $charset = mysql_client_encoding($link);
  5. if ( $charset != 'utf8' ) {
  6. mysql_set_charset('utf8',$link);
  7. }
  8.  
  9. $sql="CREATE DATABASE IF NOT EXISTS lotto ";
  10. mysql_query($sql) or die(mysql_error());
  11.  
  12.  
  13. mysql_select_db('lotto',$link);
  14. function kombi3($kk,$bb,$b,$c,$d,$e,$f){global $w;
  15. $a[1]=$bb;
  16. $a[2]=$b;
  17. $a[3]=$c;
  18. $a[4]=$d;
  19. $a[5]=$e;
  20. $a[6]=$f;
  21.  
  22. $k=0;
  23. for($i=1;$i<=4;$i++){$x1=$a[$i];
  24. $x1.='-';
  25. for($j=$i+1;$j<=5;$j++){$x2=$x1;
  26. $x2.=$a[$j];
  27. $x2.='-';
  28. for($m=$j+1;$m<=6;$m++){ $k=$k+1;
  29. $y=$x2;
  30. $y.=$a[$m];
  31. $w[$k+20*$kk]=$y;
  32. }
  33. }
  34. }
  35.  
  36.  
  37. //----------------------------------
  38. }
  39. $k=1;
  40. $sql="SELECT * FROM lotto";
  41. $result=mysql_query($sql) or die(mysql_error());
  42. $n=mysql_num_rows($result);
  43. $koniec=$n*20;
  44. $k=-1;
  45. while($row=mysql_fetch_array($result)){
  46. $k=$k+1;
  47. kombi3($k,$row[3],$row[4],$row[5],$row[6],$row[7],$row[8]);
  48.  
  49. }
  50.  
  51.  
  52. for($i=1;$i<=$koniec-1;$i++){$ile[$i]=0;
  53. for($n=1;$n<=$koniec;$n++){
  54. if($w[$i]==$w[$n]){ $ile[$i]=$ile[$i]+1 ; }
  55. }
  56.  
  57. }
  58.  
  59. $sql="DROP TABLE losy";
  60. $result=mysql_query($sql) or die(mysql_error());
  61. $sql="CREATE TABLE IF NOT EXISTS losy(
  62. id_losy int(9) NOT NULL auto_increment,
  63. losowanie_nr int(4) NOT NULL ,
  64. losy3 varchar(8) NOT NULL ,
  65. ilosc int(6) NOT NULL ,
  66.  
  67. PRIMARY KEY klucz1 (id_losy)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci; ";
  68.  
  69. mysql_query($sql) or die(mysql_error());
  70.  
  71.  
  72.  
  73. for($i=1;$i<=$koniec-1;$i++){//echo $w[$i]; echo ' ----- '; echo $ile[$i]; echo '<br>';
  74. $nlosowania=floor(($i-1)/20)+1;
  75. $sql="INSERT INTO losy (id_losy,losowanie_nr,losy3,ilosc) VALUES ('','$nlosowania','$w[$i]','$ile[$i]')";
  76. $result=mysql_query($sql) or die(mysql_error());
  77.  
  78.  
  79. }
  80.  
  81.  
  82.  
  83.  
  84.  
  85. ?>
  86.  
Deen
  1. <?php
  2. $ar1=array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9');
  3. for($i=0; $i<=9; $i++)
  4. {
  5. for($j=0;$j<count($ar1);$j++)
  6. {
  7. for($k=0;$k<count($ar1);$k++)
  8. {
  9. for($l=0;$l<count($ar1);$l++)
  10. {
  11. for($m=0;$m<count($ar1);$m++)
  12. {
  13. for($o=0;$o<count($ar1);$o++)
  14. {
  15. $one = $ar1[$i] . $ar1[$j] . $ar1[$k]. $ar1[$l]. $ar1[$m] . $ar1[$o];
  16. $dane = "$one \n";
  17. $file = "baza.txt";
  18. $fp = fopen($file, "a");
  19. flock($fp, 2);
  20. fwrite($fp, $dane);
  21. flock($fp, 3);
  22. fclose($fp);
  23. }
  24. }
  25. }
  26. }
  27. }
  28. }
  29. ?>

Jednak w pliku baza.txt ostatnia liczba to 089807 co jest nie tak?
Wicepsik
Jeśli chcesz wszystkie kombinacje od 000000 do 999999 to zastosuj taki skrypt

  1. for($i=0;$i<999999;$i++) echo sprintf("%06s\n", $i);
Deen
Nie chce cyfr... znaczy chcę litery i cyfry.
Po prostu potrzebuje skryptu który zapisze do pliku txt wszystkie mozliwe ciągi literowe od A do ZZZZZZZZZZZZZZZ
celbarowicz
deen---lenisz się , wicepsik podesłał dobry pomysł ja uzupełniłem go wskazówką --jak poprawić pomysł.

w tablicy wicepsika jest 26 znaków ---- ilość kombinacji 3 elementowych z 26 elemetów=2600

sprawdź kod:

  1. <?php
  2. $m=0;
  3. $ar1=array('a','b','c','d','e','f','trol','h','i','88','k','l','m44','n','o','p','q','r','s','t','u','v','w','x','y','z');
  4.  
  5. for($i=0; $i<=count($ar1)-2; $i++)
  6.  
  7. {
  8.  
  9. for($j=$i+1;$j<count($ar1)-1;$j++)
  10.  
  11. {
  12.  
  13. for($k=$j+1;$k<count($ar1);$k++)
  14.  
  15. {
  16.  
  17. echo $m=$m+1; echo ' '; print $ar1[$i].'-'.$ar1[$j].'-'.$ar1[$k];
  18. print "<br>";
  19.  
  20. }
  21.  
  22. }
  23.  
  24. }
  25. ?>
  26.  
  27.  
  28.  
  29.  
  30.  


wprowadzać możesz nawet różne nazwy rozdziel je tylko jakimś znakiem np '-'.
magnus
Cytat(celbarowicz @ 17.05.2010, 07:57:06 ) *
ilość kombinacji 3 elementowych z 26 elemetów=2600


Raczej 26^3 czyli 17.576
Jak dodasz cyfry to będzie 36^3 czyli 46.656

Najprostszy skrypt:
  1. for ($i=0; $i<36; $i++) {
  2. if ($i<10) {
  3. $l1 = $i;
  4. } else {
  5. $l1 = chr(55+$i);
  6. }
  7. for ($j=0; $j<36; $j++) {
  8. if ($j<10) {
  9. $l2 = $j;
  10. } else {
  11. $l2 = chr(55+$j);
  12. }
  13. for ($k=0; $k<36; $k++) {
  14. if ($k<10) {
  15. $l3 = $k;
  16. } else {
  17. $l3 = chr(55+$k);
  18. }
  19. echo $l1.$l2.$l3.';';
  20. }
  21. }
  22. }
celbarowicz
magnus , a wiesz jaka jest różnica między kombinacjami , a permutacjami i wariacjami?
z kombinacjami masz do czynienia w lotto-czyli żadna liczba nie może sią powtórzyć.
w permutacjach i wariacjach jest inaczej. jak?questionmark.gif
pozdrawiam.
thek
  1. $zestaw = array('0', '1', '2', ... , 'X', 'Y', 'Z');
  2. foreach( $zestaw AS $pierwsza ) {
  3. foreach( $zestaw AS $druga ) {
  4. foreach( $zestaw AS $trzecia ) {
  5. foreach( $zestaw AS $czwarta ) {
  6. foreach( $zestaw AS $piata ) {
  7. echo $pierwsza.$druga.$trzecia.$czwarta.$piata.' ';
  8. }
  9. }
  10. }
  11. }
  12. }
Na szybko zrobione. Określasz zestaw znaków, a ilość foreach określa ile znaków w wariacji. Tutaj jest ich 5. Zmieniaj liczbę pętli a dostaniesz inną. To co zrobiłem to wariacja z powtórzeniami, bo autor nie określił jaka ma być. Niech napisze czy z czy bez powtórzeń. Jeśli nie rozumie... czy w grupie 3 znakowej mogą czy nie powtórzyć się znaki. A więc czy możliwe jest AAA czy tylko ABC. Choć patrząc na fakt 001 i podwójnego 0 wnioskuję, że ma to być tak jak zrobiłem, a więc z powtórzeniami smile.gif
celbarowicz
jak to są kombinacje to ja jestem biskupem

thek , a wiesz jaka jest różnica między kombinacjami , a permutacjami i wariacjami?
z kombinacjami masz do czynienia w lotto-czyli żadna liczba nie może sią powtórzyć.
w permutacjach i wariacjach jest inaczej. jak?
pozdrawiam.
thek
W kombinacjach wartości mogą się powtarzać. Mój błąd jest jeden. To co zrobiłem nazwałem kombinacją z powtórzeniami choć jest to wariacja z powtórzeniami. A wnioskując z zadania to właśnie to chciał uzyskać autor. Czemu tak sądzę? Bo ma zdublowane zero. Nie wspomniał, że trójka {0, 0, 1} jest identyczna z trójką {0, 1, 0} (brak tego podpunktu a w języku potocznym wielu ludzi na wariacje mówi właśnie kombinacje) co sugeruje, że są one inne dla niego i źle dobrał on słowa. Najlepiej niech autor doprecyzuje pytanie na jakimś krótkim przykładzie... Może z zestawem {0, 1, A, B}?. Czy mają być powtórzenia, czy ważne jest umiejscowienie elementów w trójkach? Bo to nam określi z czym tak naprawdę mamy do czynienia, czy wariacją jak ja mniemam, czy faktycznie kombinacją jak się wyraził. Bo zwrot autora iż chce "od A do ZZZZZZZZZZ" sugeruje mi coś innego niż kombinacja, o którą się tak burzysz winksmiley.jpg
Deen
Ok specyfikuje...

A
B
C
...
Z
AA
AB
AC
AZ
...
BA
BB
BC
...
BZ
...
...
ZY
ZZ
AAA
AAB
.....
AAZ
AZA
AZB
etc aż do ZZZZZ

to tak samo jak chciał bym wypisać liczby tylko ze maja byc to ciągi znaków:) mało aktualne ale jak coś to będzie fajnie jak by komuś chciało się coś takiego napisac:)
thek
  1. <?php
  2. $uzywane = array('A', 'B');
  3. $ile = 3;
  4. $wynik = array();
  5. function skladaj( &$result, $collection, $depth, $prefix = '' ) {
  6. foreach( $collection AS $char ) {
  7. if( $depth > 1 ) {
  8. skladaj($result, $collection, $depth-1, $prefix.$char);
  9. } else {
  10. $result[] = $prefix.$char;
  11. }
  12. }
  13. }
  14. for($i=1; $i<=$ile; $i++)
  15. skladaj( $wynik, $uzywane, $i );
  16. ?>
  17. <pre>
  18. <?php
  19. print_r( $wynik );
  20. ?>
  21. </pre>
Poczytaj o rekurencji by zrozumieć o co tu chodzi. Zrobiłem tak by zarówno zestaw znaków wejściowych jak i głębokość były parametryzowalne. Tylko tak nie ugrzęźniesz w pętlach by skrypt nie rozrastał się kosmicznie.
DowNlOaD_
to mi drukuje:

Kod
Array
(
    [0] => A
    [1] => B
    [2] => AA
    [3] => AB
    [4] => BA
    [5] => BB
    [6] => AAA
    [7] => AAB
    [8] => ABA
    [9] => ABB
    [10] => BAA
    [11] => BAB
    [12] => BBA
    [13] => BBB
    [14] => AAAA
    [15] => AAAB
    [16] => AABA
    [17] => AABB
    [18] => ABAA
    [19] => ABAB
    [20] => ABBA
    [21] => ABBB
    [22] => BAAA
    [23] => BAAB
    [24] => BABA
    [25] => BABB
    [26] => BBAA
    [27] => BBAB
    [28] => BBBA
    [29] => BBBB
)


a czy mozna to zrobic aby bez numerku drukowalo i array?
Lars_18
Można...na przykład za pomocą foreach.

  1. <?php
  2. foreach($wynik as $value) {
  3. echo $value.'<br />';
  4. }
  5. ?>
thek
Dałem Ci gotowca, który robi to co chcesz. Ja to zapisałem do tablicy, ale jeśli Ty chcesz to w innej formie to się z tym baw już sam winksmiley.jpg W moim kodzie to raptem kilka niewielkich zmian związanych z $result. Ale nie powiem Ci jak to zrobić bo masz się czegoś sam nauczyć.

@Lars: Uwierz mi, że wcale nie trzeba wyświetlać zawartości tablicy. Wystarczy malutka zmiana w skrypcie związana z $result, a zamiast wrzucać do tablicy, funkcja zacznie pluć na ekran wszystko i print_r nie będzie potrzebne.
DowNlOaD_
zamienilem

Kod
?>
<pre>
<?php
print_r( $wynik );
?>
</pre>


na

Kod
echo(implode('<br />',$wynik));


i gitarka, all chodzi jak chcialem smile.gif

//edit: moze jest inna metoda ale ja takie cos na necie znalazlem i to wykozystam smile.gif

//edit2: jak proboje z duza iloscia znakow to zrobic z MAX 15 dlugoscia to mam error
Allowed memory size of 134217728 bytes exhausted (tried to allocate 16 bytes) eh ;/
thek
A czego się spodziewałeś? Rekurencja powoduje duże zużycie pamięci w porównaniu do normalnych skryptów. Jeśli masz możliwość zwiększ przydział pamięci dla skryptów w php.ini i po sprawie.
A to co ja mówię, to kwestia... wyrzucenia zmiennej $result oraz $wynik ze skryptu i w jednym miejscu zastąpienie jej przez echo winksmiley.jpg Jako że pokazałeś, iż mimo wszystko potrafisz coś sam od siebie zrobić ( zastosowanie implode ) to powiem, że wystarczy zrobić:
  1. <?php
  2. $uzywane = array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U');
  3. $ile = 10;
  4. function skladaj( $collection, $depth, $prefix = '' ) {
  5. foreach( $collection AS $char ) {
  6. if( $depth > 1 ) {
  7. skladaj($collection, $depth-1, $prefix.$char);
  8. } else {
  9. echo $prefix.$char.'<br />';
  10. }
  11. flush();
  12. }
  13. }
  14. for($i=1; $i<=$ile; $i++)
  15. skladaj( $uzywane, $i );
  16. ?>
Zwróć uwagę na funkcje ob_* w nowe wersji... Weź sobie je wykasuj i uruchom skrypt a potem wstaw ponownie i zobacz dlaczego się przydają. No i na bank zwiększa czas działania skryptu także w php.ini bo Ci sypnie przekroczeniem winksmiley.jpg U mnie przy zestawie liter od A do U jak powyżej i dla 10 znaków doleciało tylko do DTMOB w 60 sekund limitu winksmiley.jpg
set4812
Mhm nie jestem specjalistą ale czy nie lepiej zrobic tablice 3 wymiarową i 3 fory i kazdy by szedł od Znaku ASCI który nas interesuje numer wartośc z numeru aktualnego for przerzutować i przypisać do tablicy tongue.gif

  1. <?php
  2.  
  3. for ($i=48;$i<123;$i++){
  4. if($i==58){$i=65;}
  5. if($i==91){$i=97;}
  6. $tempi=chr($i);
  7. for ($j=48;$j<123;$j++){
  8. if($j==58){$j=65;}
  9. if($j==91){$j=97;}
  10. $tempj=chr($j);
  11.  
  12. for ($k=48;$k<123;$k++){
  13. if($k==58){$k=65;}
  14. if($k==91){$k=97;}
  15. $tempk=chr($k);
  16. echo $tempi;
  17. echo $tempj;
  18. echo $tempk;
  19. echo '</br>';
  20. }
  21. }
  22. }
  23. ?>

Skrypt długo sie ładuje ale wyswietli ci wszystkie kombinacje literocyfrowe w 3 znakach
thek
A czytałeś, że autor chce, by można było łatwo zmienić z 3 do choćby 5 lub więcej? Referencyjny jaki podałem dopiero przy dużych zestawach na pamięci się rąbię ale poza tym jest elastyczny w pełni. Twój jest nieskalowalny bo używasz przedziału znaków ASCII więc odpada dowolny w stylu $znaki = array('B', 'G', 'L') to raz. Dwa to zawsze wersja X-znakowa, gdzie kolejny to dodatkowa zagnieżdżona pętla i na dodatek ograniczona do X znaków. Nie wygeneruje zestawu znaków o długości X-1. Wrzucisz 5 pętli to wygeneruje zestawy 5-znakowe. Będziesz pisał kolejne 4 warianty identycznych pętli ale dla 1, 2, 3 i 4 stopni zagnieżdżenia? A co jeśli on chce 15 znaków dać? winksmiley.jpg będziesz walił 15 wariantów od pętli 1 stopnia zagnieżdżenia do 15 zagnieżdżonych forów? Powiedzmy, że Twój pomysł jest wersją "łopatologiczą". I po rozwiązaniach właśnie algorytmów widać, kto jest przygodnym, a kto fachowym programistą z doświadczeniem. Gdybyś zresztą zerknął do tematu wcześniej to byś widział, że taki algorytm już kilka osób podało na pętlach, tyle że nie bawili się niepotrzebnie w znaki ASCII, tylko zestaw znaków dali jak tablicę dla pętli foreach.
set4812
ja jestem poczatkujacy smile.gif twego kodu nie rozumiem poki co za bardzo smile.gif znaki bgl wygeneruje moj kod oraz wszystkie kombinacje

nie musze pisac sam forow i ich zagniezdzac moge napisac funkcje ktore za mnie je zagniezdzi w zaleznosci od ilości znaków
celbarowicz
deen gdzie jesteś? podziękuj thekoowi.
thek
Set... I właśnie pisząc funkcję zagnieżdżającą będziesz musiał odwołać się do rekurencji winksmiley.jpg Zauważ, że ja tak właśnie zrobiłem. Dopóki parametr $depth ma określoną wartość - zagłęb się bardziej. A potem na pętli for lecę wszystkie możliwości od 1 do X znaków smile.gif Bez -> for($i=1; $i<=$ile; $i++) zrobiłbym jedynie wypisanie określonej ilości znaków, czyli albo 2, albo 3, albo 4-znakowe wariacje winksmiley.jpg Jeśli autor zechce tylko 10-znakowe bez krótszych, to wywoła:
skladaj( $uzywane, 10 ) i to będzie wszystko na temat. Dlatego jeśli nie wiesz co się w moim kodzie dzieje... przeanalizuj a zobaczysz prosty mechanizm rekurencji.
EDIT: celbartowicz, nie trzeba mi dziękować smile.gif Moderatorzy, Admini i ogólnie cały zarząd to ludzie, którzy mają wiedzę i nie wahają się jej użyć winksmiley.jpg Jeśli pomagamy to dlatego że chcemy, nie dlatego, że liczymy na podziękowania by podnieść sobie ego biggrin.gif Jakoś nie karzemy tych, którzy nie dziękują winksmiley.jpg
set4812
thek już rozumiem twój skrpt, może zadam głupie pytanie ale czy da sie foreach przeleciec jakos ASCI??
Fifi209
Cytat(set4812 @ 13.06.2010, 10:41:06 ) *
thek już rozumiem twój skrpt, może zadam głupie pytanie ale czy da sie foreach przeleciec jakos ASCI??


Zrób sobie tablice z liczbami odpowiadającymi danym znakom i możesz lecieć foreach
set4812
to ja juz wole zapełnic tablice znakami a nie liczbami a potem rzutować
Fifi209
Cytat(set4812 @ 13.06.2010, 12:16:45 ) *
to ja juz wole zapełnic tablice znakami a nie liczbami a potem rzutować


Lepiej wygenerować ją jeden raz i wygenerowaną wstawić do skryptu. Np. jako

[klucz_liczba] -> wartość znak
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.