Source of packages/Combie/Math/Permutation/Array2Dim.php
<?php
/**
* Permutationen 2 dim
*
* Vertauschen von Array Elementen
*
* @filesource
* @author Combie <uli@combie.de>
* @version $Id$
* @package Combie
* @subpackage Math
*/
namespace Combie\Math\Permutation;
/**
* Permutation eines 2 dimensionalen Arrays
*
* Vertauschen von Elementen
*
* @example packages/Combie/tests/math/test_permutation_2dim.php
* @package Combie
* @subpackage Math
*/
class Array2Dim implements \Countable, \ArrayAccess, \Iterator
{
/**
* Interne Variable
* @var array interne ReprÃÂäsentation
*/
private $array = array();
/**
* Interne Variable
* @var interger Anzahl aller mÃÂöglichen Vertauschungen
*/
private $count = 0;
/**
* Interne Variable
* @var integer inter Zeiger fÃÂür die ArrayAccess Schnittstelle
*/
private $pos = 0;
/**
* Permutation 2 Dim
*
* Interne Helfer Funktion
* Erzeugt alle Permutationen eines ein Dimensionalen Arrays
*
* @param array Das Array mit den Elementen, welche vertauscht werden sollen
* @return void Keine RÃÂückgabe
*/
public function __construct(Array $array)
{
$array = array_values($array); // normalisieren
foreach($array as $index => &$teilarray)
{
if(!is_array($teilarray))
throw new \InvalidArgumentException('Only Arrays allowed',1);
if(count($teilarray) < 1)
throw new \InvalidArgumentException("Too few Elements in Subarray $index",2);
$this->array[$index]['data'] = array_values($teilarray); // normalisieren
$this->array[$index]['fence'] = 1; // provisorisch
$this->array[$index]['count'] = count($teilarray);
}
for ($i=count($this->array)-1;$i>0;$i--)
$this->array[$i-1]['fence'] = $this->array[$i]['fence']*$this->array[$i]['count'];
$this->count = $this->array[0]['fence']*$this->array[0]['count'];
if(!is_int($this->count))
throw new \InvalidArgumentException('Too many elements for Integer Count',3);
}
/**
* Holt gezielt eine Vertauschung
*
* Diese Methode ist Teil der ArrayAccess Schnittstelle
*
* @param index Index der gewÃÂünschten Vertauschung
* @return array Vertauschung
*/
public function offsetGet($index)
{
if(!$this->offsetExists($index))
throw new \InvalidArgumentException('Offset out of Range',4);
$result = array();
foreach($this->array as &$teilarray)
{
$result[] = $teilarray['data'][floor($index/$teilarray['fence'])];
$index = $index % $teilarray['fence'];
}
return $result;
}
/**
* VollstÃÂändige Permutation eines 2 Dimensionalen Arrays
*
*
*
* @param array Das Array mit den Elementen, welche vertauscht werden sollen
* @return array Ein Array mit allen mÃÂöglichen Vertauschungen
*/
public static function getAll(Array $array)
{
$result = array();
foreach($array as $subarray)
{
$zwischenlager = array();
if(empty($result))
foreach($subarray as $element)
$zwischenlager[] = array($element);
else
foreach($result as $alte)
foreach($subarray as $element)
$zwischenlager[] = array_merge($alte,array($element));
$result = $zwischenlager;
}
return $result;
}
/**
* PrÃÂüft ob der Index gÃÂültig ist
*
* Diese Methode ist Teil der ArrayAccess Schnittstelle
*
* @param index Index der gewÃÂünschten Vertauschung
* @return boolean verfÃÂügbar
*/
public function offsetExists($index)
{
return $index >= 0 && $index < $this->count;
}
/**
* PrÃÂüft ob der interne Zeiger gÃÂültig ist
*
* Diese Methode ist Teil der Iterator Schnittstelle
*
* @return boolean verfÃÂügbar
*/
public function valid()
{
return $this->offsetExists($this->pos);
}
/**
* PrÃÂüft ob der interne Zeiger gÃÂültig ist
*
* Diese Methode ist Teil der Countable Schnittstelle
*
* @return integer Anzahl mÃÂöglicher Vertauschungen
*/
public function count()
{
return $this->count;
}
/**
* Setzt den interne Zeiger wieder aud Anfang
*
* Diese Methode ist Teil der Iterator Schnittstelle
*
* @return void Keine RÃÂückgabe
*/
public function rewind()
{
$this->pos = 0;
}
/**
* Holt die Vertauschung auf die der interne Zeiger verweist
*
* Diese Methode ist Teil der Iterator Schnittstelle
*
* @return array Aktuelle Vertauschung
*/
public function current()
{
return $this[$this->pos];
}
/**
* Holt den internen Zeiger, also den Array Index
*
* Diese Methode ist Teil der Iterator Schnittstelle
*
* @return array Aktuelle Vertauschung
*/
public function key()
{
return $this->pos;
}
/**
* Setzt den interne Zeiger eine Position weiter
*
* Diese Methode ist Teil der Iterator Schnittstelle
*
* @return void Keine RÃÂückgabe
*/
public function next()
{
$this->pos++;
}
/**
* nicht implementiert
*
* Diese Methode ist Teil der ArrayAccess Schnittstelle
*
* @return void Keine RÃÂückgabe
*/
public function offsetSet($index,$newval)
{
throw new \Exception('Setter not implemented',5);
}
/**
* nicht implementiert
*
* Diese Methode ist Teil der ArrayAccess Schnittstelle
*
* @return void Keine RÃÂückgabe
*/
public function offsetUnset($index)
{
throw new \Exception('Unsetter not implemented',6);
}
}