Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Efekt rekurencji bez rekurencji, tabelka tabelek.
Forum PHP.pl > Forum > PHP
sanneo
Witajcie.

Próbuję rozwiązać swój problem dotyczący efektu rekurencji bez rekurencji, a to z powodu ograniczeń PHP co do rekurencji do 100 poziomu.

Moim celem jest wygenerowanie tabelki tabelek, które składają się na strukturę jak w linku poniżej, bez ograniczeń co do zagłębienia, jedyne ograniczenie, które akceptuję, to limit pamięci RAM komputera (HTML w przeglądarce).

Efekt jaki chcę uzyskać (bez zagłębienia):

http://sanneo.nazwa.pl/_tmp/tabela1.html

Drugi poziom zagłębienia i kolejne:

http://sanneo.nazwa.pl/_tmp/tabela2.html
http://sanneo.nazwa.pl/_tmp/tabela3.html
http://sanneo.nazwa.pl/_tmp/tabela4.html

Próbuję już od wielu godzin, ale bez rezultatu.

Proszę o pomoc.

Pozdrawiam.
Mariusz (sanneo)
erix
Cytat
Próbuję rozwiązać swój problem dotyczący efektu rekurencji bez rekurencji, a to z powodu ograniczeń PHP co do rekurencji do 100 poziomu.

Możesz zwiększyć limit. [;

A iteracyjnie, to przychodzi mi do głowy potęgowanie maksymalnej wartości licznika; dla uproszczenia zrobię kolumnami. Niestety, później musisz ręcznie modyfikować colspan dla wyższych poziomów:

Kod
pętla dla wierszy(a=0;a<max;a++)
   pętla dla kolumn(b=0;b<a^2;b++)


I to w sumie wszystko; potem idziesz od dołu i odwrotnie colspana zwiększasz. [;
mortus
Może jakoś tak:
  1. $table = '<table cellspacing="0"><tr><td style="border: 1px solid #333;" rowspan="2">1</td><td style="border: 1px solid #333;">2</td></tr><tr><td style="border: 1px solid #333;">3</td></tr></table>';
  2.  
  3. function generate($what) {
  4. return '<table cellspacing="0"><tr><td rowspan="2" style="border: 1px solid #333;">1</td><td style="border: 1px solid #333;">'.$what.'</td></tr><tr><td style="border: 1px solid #333;">'.$what.'</td></tr></table>';
  5. }
  6.  
  7. for($i = 0; $i < 15; $i++) {
  8. $table = generate($table);
  9. }
  10. echo $table;

Tutaj użyłem pętli for i 15 iteracji,bo na tyle pozwolił mi mój PC.

EDIT: Poprawione co nieco.
Orzeszekk
Ew jak sobie lubisz komplikowac zycie to tak :
  1. public function draw ()
  2. {
  3. $current = 0;
  4. $objectsStack[] = $this;
  5. $nodeCounter[] = 0;
  6. DrawElement: echo '<', $objectsStack[$current]->name;
  7. if ($objectsStack[$current]->attributes)
  8. {
  9. foreach ($objectsStack[$current]->attributes as $name => $value)
  10. {
  11. echo ' ', $name, '="', $value, '"';
  12. }
  13. }
  14. if (($objectsStack[$current]->content) || (!($objectsStack[$current]->shortable)))
  15. {
  16. echo '>';
  17. DrawContent: if (($objectsStack[$current]->content[$nodeCounter[$current]]))
  18. {
  19. if ($objectsStack[$current]->content[$nodeCounter[$current]]->name)
  20. {
  21. $objectsStack[$current + 1] = $objectsStack[$current]->content[$nodeCounter[$current]];
  22. ++$current;
  23. $nodeCounter[$current] = 0;
  24. goto DrawElement;
  25. }
  26. else
  27. {
  28. echo $objectsStack[$current]->content[$nodeCounter[$current]];
  29. ++$nodeCounter[$current];
  30. goto DrawContent;
  31. }
  32. }
  33. else
  34. {
  35. echo '</', $objectsStack[$current]->name, '>';
  36. if ($current)
  37. {
  38. --$current;
  39. ++$nodeCounter[$current];
  40. goto DrawContent;
  41. }
  42. }
  43. }
  44. else
  45. {
  46. echo '/>';
  47. if ($current)
  48. {
  49. --$current;
  50. ++$nodeCounter[$current];
  51. goto DrawContent;
  52. }
  53. }
  54. }


sztuczna rekurencja zrobiona na skokach GOTO dodanych w 5.3. to akurat zamienia drzewo dom na kod html. $objectsStack[] to stos.
z czytelnoscia kodu nie ma to nic wspolnego biggrin.gif ale jest szybsze niz natywna rekurencja nawet.
sanneo
Witajcie.

Dzięki za podpowiedzi, ale to nie zadziała w moim przypadku.

Z propozycji erix, nie mogę skorzystać, propozycja mortus, powoduje zajęcie pamięci PHP, propozycja Orzeszekk jest wycięta z jakiejś klasy, ale chyba ta klasa służy do czegoś innego.

Mimo to, poczyniłem kolejne "postępy".

Aby tabelka została wygenerowana prawidłowo, potrzebuję już tylko utworzyć następujący ciąg cyfr:

1-szy poziom zagłębienia:
0

2-gi poziom zagłębienia:
0, 1, 0

3-ci poziom zagłębienia:
0, 1, 0, 2, 0, 1, 0

4-ty poziom zagłębienia
0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0

5-ty poziom zagłębienia:
0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0

6-ty poziom zagłębienia:
0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0

Funkcja generująca ten ciąg znaków powinna zawierać jeden parametr odnoszący się do poziomu zagłębienia.

Proszę o pomoc.

Pozdrawiam.
Mariusz (sanneo)
Piogola
  1. function gener($x){
  2. for($i=0;$i<$x;$i++){
  3. $s = $e.' '.$i.','.$e;
  4. $e = $s;
  5. }
  6. return $s;
  7. }
sanneo
Witam.

Dzięki za pomoc.

Dla zainteresowanych zamieszczam cały kod poniżej.

Jeszcze pewnie będę to jakoś optymalizował, ale efekt jest taki jak potrzebuję smile.gif

Pozdrawiam.
Mariusz (sanneo)

  1. <style type="text/css">
  2. table {
  3. border-collapse: collapse;
  4. }
  5. td {
  6. padding: 5px 10px;
  7. border: solid 1px red;
  8. }
  9. </style>
  10. <?php
  11. class tableOfTables
  12. {
  13. private $_depthLevel;
  14.  
  15. public function __construct($depthLevel = 1){
  16. $this->_depthLevel = $depthLevel;
  17. }
  18. public function generateHTML($HTMLBlockCode){
  19. $HTMLBlocksCodeArray = array(
  20. 'a' => array(0, 1, 2, 7, 4, 3),
  21. 'b' => array(0, 1, 2, 7, 4, 3, 8, 4, 5, 1, 3, 9, 4, 5, 6),
  22. 'c' => array(4, 5, 1, 3),
  23. 'd' => array(4, 5, 6),
  24. );
  25. $HTMLElementsArray = array(
  26. '<table>', // 0
  27. '<tr>', // 1
  28. '<td rowspan="2">', // 2
  29. '<td>', // 3
  30. '</td>', // 4
  31. '</tr>', // 5
  32. '</table>', // 6
  33. '1', // 7
  34. '2', // 8
  35. '3', // 9
  36. );
  37. $out = '';
  38. $HTMLBlocksCode = $HTMLBlocksCodeArray[$HTMLBlockCode];
  39. foreach($HTMLBlocksCode as $HTMLElementIndex){
  40. $out .= $HTMLElementsArray[$HTMLElementIndex];
  41. }
  42. return $out;
  43. }
  44. public function createDepthSeparator(){
  45. for($a = 0; $a < $this->_depthLevel; $a++){
  46. $c = $b . $a . $b;
  47. $b = $c;
  48. }
  49. return $c;
  50. }
  51. public function createTable($depthLevel = 1){
  52.  
  53. $this->_depthLevel = $depthLevel;
  54. $depthSeparator = $this->createDepthSeparator();
  55.  
  56. $tableContentsHTMLBlocks = pow(2, $this->_depthLevel);
  57.  
  58. // Create all opens
  59. echo str_repeat($this->generateHTML('a'), $this->_depthLevel);
  60.  
  61. // Create table contents
  62. for($a = 0; $a < $tableContentsHTMLBlocks; $a++){
  63. echo $this->generateHTML('b');
  64. if($a < ($tableContentsHTMLBlocks-1)){
  65. echo str_repeat($this->generateHTML('d'), substr($depthSeparator, $a, 1));
  66. echo $this->generateHTML('c');
  67. echo str_repeat($this->generateHTML('a'), substr($depthSeparator, $a, 1));
  68. }
  69. }
  70. // Create all closes
  71. echo str_repeat($this->generateHTML('d'), $this->_depthLevel);
  72. }
  73. }
  74. $table = new tableOfTables();
  75. $table->createTable(5);
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.