ugrás a tartalomhoz

Php - fa kezelése

inf · 2010. Aug. 4. (Sze), 00.22
Sziasztok!

Szeretnék fa kezelő osztályt készíteni php-ben, de egy kicsit elakadtam. Mmint azzal kapcsolatban, hogy hogyan is kéne ezt.

Konkrétan arra gondoltam, hogy tömbbe rakom a kulcsokat és szerializálom a tömböt, így kapok egy hashKey-t, amivel már le tudom tárolni a fa alkotóit egy szimpla tömbben. Gondolom feltaláltam a spanyol viaszt :-) Nem is ez a lényeg, hanem hogy ez így mennyire optimális, vagy hogy érdemes e egyáltalán így tárolni?

(Készítettem egy ilyen fát felhasználó osztályt, és a végeredmény szerintem elég lassú lett, viszont van egy olyan előnye, hogy nem kell törődni azzal, hogy egy levél megadásánál az összes szülő ágat hozzáadjam a rendszerhez.)

Ha esetleg tudnátok ezzel kapcsolatban bármilyen irodalmat, weblapot, ilyesmit ajánlani, azt megköszönném. Próbáltam keresni, de sajnos nem tudom, hogy mi a kifejezés erre a fa megvalósítási módszerre.
 
1

Hierarchikus adatkezelés SQL-lel PHP-ben

Poetro · 2010. Aug. 4. (Sze), 00.28
Ajánlom olvasd el a teljes cikksorozatot a témában: Hierarchikus adatkezelés SQL-lel PHP-ben
2

Köszi, de már olvastam meg

inf · 2010. Aug. 4. (Sze), 01.15
Köszi, de már olvastam meg használtam is, amúgy nagyon jó cikksorozat.
Nekem nem az SQL-el van gondom, de mutatok példákat, hogy érthetőbb legyen:

DOM szerű tárolási mód:

class Tree1
{
	public $children=array();
	public $data;
	
	public function __construct($data='generált')
	{
		$this->data=$data;
	}
	
	public function put($keyList,Tree1 $value)
	{
		$k=array_pop($keyList);
		$current=$this;
		foreach ($keyList as $key)
		{
			if (!isset($current->children[$key]))
			{
				$current->children[$key]=new Tree1();
			}
			$current=$current->children[$key];
		}
		$current->children[$k]=$value;
		return $this;
	}
	
	public function get($keyList)
	{
		$current=$this;
		foreach ($keyList as $key)
		{
			if (!isset($current->children[$key]))
			{
				return;
			}
			$current=$current->children[$key];
		}
		return $current;
	}
}

$t=new Tree1('gyökér');
$t->put(array('a','b','c'),new Tree1('egy levél'));
echo $t->get(array('a','b','c'))->data;
echo '<br />';
echo '<pre>';
var_dump($t);
echo '</pre>';
Map-es tárolási mód:

class Tree2
{
	public $map=array();
	
	protected function hashCode($keyList)
	{
		return serialize($keyList);
	}
	
	public function put($keyList,$data)
	{
		$this->map[$this->hashCode($keyList)]=&$data;
		return $this;
	}
	
	public function get($keyList)
	{
		if (isset($this->map[$this->hashCode($keyList)]))
		{
			return $this->map[$this->hashCode($keyList)];
		}
	}
}

$t=new Tree2();
$t->put(array('a','b','c'),'ez egy levél');
echo $t->get(array('a','b','c'));
echo '<br />';
echo '<pre>';
var_dump($t);
echo '</pre>';
A másodikat vagy ahhoz hasonlót szeretnék használni, de ha lehet a fentinél hatékonyabb algoritmussal. (Már ha van ilyen.)
5

Na gányoltam egy olyan

inf · 2010. Aug. 5. (Cs), 05.32
Na gányoltam egy olyan osztályt, ami nekem kell. Egész jól használható a speckó multitonomhoz. Majd valszeg bővülni fog még néhány dologgal. Nem próbáltam még, hogy a Node-kből összerakott fánál gyorsabb e, de ránézésre bizonyos helyzetekben mindenképp jobb...

class Tree implements \IteratorAggregate
{
	static public function instance()
	{
		$class=get_called_class();
		return new $class();
	}

	protected $delimiter='/';
	protected $absolute='';
	protected $value_map;
	protected $instance_map;
	
	public function __construct()
	{
		$this->value_map=array();
		$this->instance_map=array();
		$this->instance_map[$this->absolute]=$this;
	}
	
	public function setDelimiter($delimiter)
	{
		$this->delimiter=$delimiter;
		return $this;
	}
	
	public function getDelimiter()
	{
		return $this->delimiter;
	}
	
	public function getIterator()
	{
		return new \ArrayIterator($this->value_map);
	}
	
	protected function absolute($key)
	{
		return ($key=='' || $key=='.')
			?$this->absolute
			:(
				($key=='..')
				?substr($this->absolute,strrpos($this->absolute,$this->delimiter))
				:($this->absolute.$this->delimiter.$key)
			);
	}
	
	public function put($key,&$value)
	{
		$this->value_map[$this->absolute($key)]=&$value;
		return $this;
	}
	
	public function contains($key)
	{
		return isset($this->value_map[$this->absolute($key)]);
	}
	
	public function &get($key)
	{
		return $this->value_map[$this->absolute($key)];
	}
	
	public function select($key)
	{
		$absolute=$this->absolute($key);
		if (!isset($this->instance_map[$absolute]))
		{
			$class=get_called_class();
			$tree=new $class();
			$tree->absolute=$absolute;
			$tree->delimiter=&$this->delimiter;
			$tree->value_map=&$this->value_map;
			$tree->instance_map=&$this->instance_map;
			$this->instance_map[$absolute]=$tree;
		}
		return $this->instance_map[$absolute];
	}
}
3

Composite patternt nézted

Ifju · 2010. Aug. 4. (Sze), 10.06
Composite patternt nézted már?
4

Igen, ismerem a Composite

inf · 2010. Aug. 4. (Sze), 13.12
Igen, ismerem a Composite pattern-t.