کد
<?php
namespace Techanic\CS\DS\Linear\Vector;
include_once '../1- One-dimensional array (Simple array)/one-dimensional-array.php';
use Exception;
interface TwoDimArrayInterface
{
function __construct(int $rows, int $sols);
function Size() : array; // [rows, cols]
}
abstract class AbstractTwoDimArray implements TwoDimArrayInterface, \ArrayAccess
{
/**
*
* @var array
*/
private /*array*/ $_size = [0, 0];
/**
*
* @var array
*/
private /*array*/ $_rows = [];
protected abstract function getValueType() : string;
protected abstract function getDefaultValue();
public function __construct(int $rows, int $cols)
{
if ($rows < 0)
throw new Exception('rows must be positive number.');
if ($cols < 0)
throw new Exception('cols must be positive number.');
$this->_size = [$rows, $cols];
$defaultValue = $this->getDefaultValue();
if (gettype($defaultValue) != $this->getValueType())
throw new Exception('Return type of the getDefaultValue() does not match getValueType().');
for ($row = 0; $row < $this->_size[0]; $row++)
{
$this->_rows[$row] = OneDimArrayFactory::Make($this->getValueType(), $this->_size[1]);
for ($col = 0; $col < $this->_size[1]; $col++)
($this->_rows[$row])[$col] = $defaultValue;
}
}
public function Size(): array
{
return $this->_size;
}
public function offsetSet($row, $value)
{
if (gettype($row) != gettype(0))
throw new Exception('The index must be of type ' . gettype(0));
if ($row < 0 || $row >= $this->_size[0])
throw new Exception('The index must be in the range (0, ' . ($this->_size[0] -1) . ')');
if (!($value instanceof OneDimArrayInterface)) // TODO: check more accurate constraint
throw new Exception('The value must be of type OneDimArrayInterface');
if ($value->Size() != $this->_size[1])
throw new Exception('The value size does not match.');
$this->_rows[$row] = $value;
}
public function offsetExists($row)
{
if (gettype($row) != gettype(0))
throw new Exception('The index must be of type ' . gettype(0));
return ($row >=0 && $row < $this->_size[0]);
}
public function offsetGet($row)
{
if (gettype($row) != gettype(0))
throw new Exception('The index must be of type ' . gettype(0));
return $this->_rows[$row];
}
public function offsetUnset($row)
{
if (gettype($row) != gettype(0))
throw new Exception('The index must be of type ' . gettype(0));
$this->_rows[$row] = OneDimArrayFactory::Make($this->getValueType, $this->_size[1]);
}
}
class IntTwoDimArray extends AbstractTwoDimArray
{
protected function getValueType() : string
{
return gettype(0);
}
protected function getDefaultValue()
{
return 0;
}
}
class FloatTwoDimArray extends AbstractTwoDimArray
{
protected function getValueType() : string
{
return gettype(1.0);
}
protected function getDefaultValue()
{
return 0.0;
}
}
class StringTwoDimArray extends AbstractTwoDimArray
{
protected function getValueType() : string
{
return gettype('');
}
protected function getDefaultValue()
{
return '';
}
}
class TwoDimArrayFactory
{
public static function Make(string $type, int $rows, int $cols)
{
switch ($type)
{
case 'int':
case 'integer':
return new IntTwoDimArray($rows, $cols);
break;
case 'float':
case 'double':
return new FloatTwoDimArray($rows, $cols);
break;
case 'string':
return new StringTwoDimArray($rows, $cols);
break;
default:
throw new Exception('TwoDimArray is not implemented for the type ' . $type);
break;
}
}
}
$rows = 5;
$cols = 5;
$intMatrix = TwoDimArrayFactory::Make(gettype(0), $rows, $cols);
for ($row = 0; $row < $intMatrix->Size()[0]; $row++) {
for ($col = 0; $col < $intMatrix->Size()[1]; $col++)
echo $intMatrix[$row][$col] . ' ';
echo PHP_EOL;
}
echo PHP_EOL;
for ($row = 0; $row < $intMatrix->Size()[0]; $row++) {
for ($col = 0; $col < $intMatrix->Size()[1]; $col++)
$intMatrix[$row][$col] = $row + $col;
}
for ($row = 0; $row < $intMatrix->Size()[0]; $row++) {
for ($col = 0; $col < $intMatrix->Size()[1]; $col++)
echo $intMatrix[$row][$col] . ' ';
echo PHP_EOL;
}
echo PHP_EOL;