sanneo
11.01.2012, 22:17:17
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.htmlDrugi poziom zagłębienia i kolejne:
http://sanneo.nazwa.pl/_tmp/tabela2.htmlhttp://sanneo.nazwa.pl/_tmp/tabela3.htmlhttp://sanneo.nazwa.pl/_tmp/tabela4.htmlPróbuję już od wielu godzin, ale bez rezultatu.
Proszę o pomoc.
Pozdrawiam.
Mariusz (sanneo)
erix
11.01.2012, 22:42:48
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
12.01.2012, 00:18:35
Może jakoś tak:
$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>';
function generate($what) {
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>';
}
for($i = 0; $i < 15; $i++) {
$table = generate($table);
}
Tutaj użyłem pętli for i 15 iteracji,bo na tyle pozwolił mi mój PC.
EDIT: Poprawione co nieco.
Orzeszekk
12.01.2012, 00:55:34
Ew jak sobie lubisz komplikowac zycie to tak :
public function draw ()
{
$current = 0;
$objectsStack[] = $this;
$nodeCounter[] = 0;
DrawElement
: echo '<', $objectsStack[$current]->name; if ($objectsStack[$current]->attributes)
{
foreach ($objectsStack[$current]->attributes as $name => $value)
{
echo ' ', $name, '="', $value, '"'; }
}
if (($objectsStack[$current]->content) || (!($objectsStack[$current]->shortable)))
{
DrawContent: if (($objectsStack[$current]->content[$nodeCounter[$current]]))
{
if ($objectsStack[$current]->content[$nodeCounter[$current]]->name)
{
$objectsStack[$current + 1] = $objectsStack[$current]->content[$nodeCounter[$current]];
++$current;
$nodeCounter[$current] = 0;
goto DrawElement;
}
else
{
echo $objectsStack[$current]->content[$nodeCounter[$current]]; ++$nodeCounter[$current];
goto DrawContent;
}
}
else
{
echo '</', $objectsStack[$current]->name, '>'; if ($current)
{
--$current;
++$nodeCounter[$current];
goto DrawContent;
}
}
}
else
{
if ($current)
{
--$current;
++$nodeCounter[$current];
goto DrawContent;
}
}
}
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

ale jest szybsze niz natywna rekurencja nawet.
sanneo
13.01.2012, 19:02:27
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)
sanneo
14.01.2012, 21:13:58
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ę

Pozdrawiam.
Mariusz (sanneo)
<style type="text/css">
table {
border-collapse: collapse;
}
td {
padding: 5px 10px;
border: solid 1px red;
}
</style>
<?php
class tableOfTables
{
private $_depthLevel;
public function __construct($depthLevel = 1){
$this->_depthLevel = $depthLevel;
}
public function generateHTML($HTMLBlockCode){
$HTMLBlocksCodeArray = array( 'a' => array(0, 1, 2, 7, 4, 3), 'b' => array(0, 1, 2, 7, 4, 3, 8, 4, 5, 1, 3, 9, 4, 5, 6), 'c' => array(4, 5, 1, 3), );
$HTMLElementsArray = array( '<table>', // 0
'<tr>', // 1
'<td rowspan="2">', // 2
'<td>', // 3
'</td>', // 4
'</tr>', // 5
'</table>', // 6
'1', // 7
'2', // 8
'3', // 9
);
$out = '';
$HTMLBlocksCode = $HTMLBlocksCodeArray[$HTMLBlockCode];
foreach($HTMLBlocksCode as $HTMLElementIndex){
$out .= $HTMLElementsArray[$HTMLElementIndex];
}
return $out;
}
public function createDepthSeparator(){
for($a = 0; $a < $this->_depthLevel; $a++){
$c = $b . $a . $b;
$b = $c;
}
return $c;
}
public function createTable($depthLevel = 1){
$this->_depthLevel = $depthLevel;
$depthSeparator = $this->createDepthSeparator();
$tableContentsHTMLBlocks = pow(2, $this->_depthLevel);
// Create all opens
// Create table contents
for($a = 0; $a < $tableContentsHTMLBlocks; $a++){
echo $this->generateHTML('b'); if($a < ($tableContentsHTMLBlocks-1)){
echo $this->generateHTML('c'); }
}
// Create all closes
}
}
$table = new tableOfTables();
$table->createTable(5);