یک پیادهسازی از دادهساختار آرایهی ساده در پیاچپی (PHP)، نسخه ۱
در این نسخه از پیاده سازی ساختار داده آرایه در PHP، ما از روش ساده بدون استفاده از ویژگی های پیشرفته تر PHP (مانند تکرارکننده ها) استفاده می کنیم. به دلیل نگرش گام به گام این مقالات (منظور نسخه های بعدی است) سعی می کنیم از کدهای سازگار در کنار همه نسخه ها استفاده کنیم.
نتیجه نهایی مطلوب، کلاسی به نام IntOneDimArray
(و همچنین FloatOneDimArray
و غیره) است که توسط عبارت مقداردهی اولیه $intArray = new IntOneDimArray($size);
استفاده می شود. و بعداً توسط ستتر و دریافت کننده ها مانند این استفاده می شود:
echo $intArray->Set($i, $v)
echo $intArray->Get($i)
در ابتدا، یک کلاس انتزاعی ساده به نام AbstractOneDimArray
ایجاد می کنیم.
اولین چیزی که در مورد آرایه های ساده یاد می گیریم این است که محدودیتی برای تعداد آیتم ها وجود دارد. (قابل تغییر در مورد آرایه پویا و ثابت در صورت آرایه ثابت یا ثابت) ما تمایل به پیاده سازی آرایه ساده داریم و منظور از ساده نیز اندازه ثابت است.
protected $_size = 0;
ما از آرایه داخلی پیاچپی (PHP) به عنوان نگهدارنده داده برای ساختار داده خود استفاده می کنیم. (با این که مسخره به نظر می رسد، اما ما بر اهداف آموزشی تمرکز می کنیم)
protected $_values = [];
برای دسترسی به اندازهی آرایه یک متد Size پیادهسازی میکنیم.
public function Size() : int
{
return $this->_size;
}
تا اینجای کار، کلاس پیادهسازی شده به شکل زیر است:
abstract class AbstractOneDimArray
{
protected $_size = 0;
protected $_values = [];
public function __construct(int $size)
{
if ($size < 0)
throw new \Exception('Size must be positive number.');
$this->_size = $size;
}
public function Size() : int
{
return $this->_size;
}
}
به دلیل این که کلاس انتزاعی ما باید به عنوان یک والد برای کلاسهای واقعی عمل کند و هر کلاس فرزند، نوع دادهی مشخصی دارد، یک متد انتزاعی getValueType
اعلان میکنیم که در هر کلاس فرزند باید پیادهسازی شود.
protected abstract function getValueType() : string;
همچنین یک متد انتزاعی دیگر اعلان میکنیم که مقدار پیشفرض نوع دادهی مشخص شده را برمیگرداند.
protected abstract function getDefaultValue();
در سازندهی کلاس والد، از این دو متد به شکل زیر استفاده میکنیم.
public function __construct(int $size)
{
if ($size < 0)
throw new Exception('Size must be positive number.');
$this->_size = $size;
$defaultValue = $this->getDefaultValue();
if (gettype($defaultValue) != $this->getValueType())
throw new Exception('Return type of the getDefaultValue() does not match getValueType().');
for ($i = 0; $i _size; $i++)
$this->_values[$i] = $defaultValue;
}
البته باید حاوی متدهای getter و setter باشد تا یک کلاس والد ساختار داده آرایه باشد! پیادهسازی این دو متد به صورت زیر است
public function Set(int $index, $value)
{
if ($index < 0 || $index >= $this->_size)
throw new Exception('The index must be in the range (0, ' . ($this->_size -1) . ')');
if (gettype($value) != $this->getValueType())
throw new Exception('The value must be of type ' . $this->getValueType());
$this->_values[$index] = $value;
}
public function Get(int $index)
{
if ($index < 0 || $index >= $this->_size)
throw new Exception('The index must be in the range (0, ' . ($this->_size -1) . ')');
return $this->_values[$index];
}
کلاس پایه اکنون کامل شده و به صورت زیر است
abstract class AbstractOneDimArray
{
/**
*
* @var int
*/
protected /*int*/ $_size = 0;
/**
*
* @var array
*/
protected /*array*/ $_values = [];
protected abstract function getValueType() : string;
protected abstract function getDefaultValue();
public function __construct(int $size)
{
if ($size < 0)
throw new Exception('Size must be positive number.');
$this->_size = $size;
$defaultValue = $this->getDefaultValue();
if (gettype($defaultValue) != $this->getValueType())
throw new Exception('Return type of the getDefaultValue() does not match getValueType().');
for ($i = 0; $i < $this->_size; $i++)
$this->_values[$i] = $defaultValue;
}
public function Size() : int
{
return $this->_size;
}
public function Set(int $index, $value)
{
if ($index < 0 || $index >= $this->_size)
throw new Exception('The index must be in the range (0, ' . ($this->_size -1) . ')');
if (gettype($value) != $this->getValueType())
throw new Exception('The value must be of type ' . $this->getValueType());
$this->_values[$index] = $value;
}
public function Get(int $index)
{
if ($index < 0 || $index >= $this->_size)
throw new Exception('The index must be in the range (0, ' . ($this->_size -1) . ')');
return $this->_values[$index];
}
}
حال برای استفاده از این کلاس پایه، باید یک کلاس واقعی (غیرانتزاعی) را مشتق کنیم. برای نمونه کلاس IntOneDimArray
را برای ساخت آرایهای از اعداد صحیح میسازیم.
class IntOneDimArray extends AbstractOneDimArray
{
protected function getValueType() : string
{
return gettype(0);
}
protected function getDefaultValue()
{
return 0;
}
}
همانطور که مشاهده میکنید، تنها باید دو متد getValueType
و getDefaultValue
را پیاده کنیم. بقیهی عملیات از کلاس پایه به ارث میرسد. بیایید کد توسعه یافته را با یک مثال اجرایی بررسی کنیم.
$size = 5;
$intArray = new IntOneDimArray($size);
for ($i = 0; $i Size(); $i++) {
echo $intArray->Get($i) . ', ';
}
echo PHP_EOL;
for ($i = 0; $i Size(); $i++) {
$intArray->Set($i, $i);
}
for ($i = 0; $i Size(); $i++) {
echo $intArray->Get($i) . ', ';
}
echo PHP_EOL;
echo $intArray->Get($size);
خروجی این کد به شکل زیر خواهد بود:
0, 0, 0, 0, 0 0, 1, 2, 3, 4 5
کد
<?php
namespace Techanic\CS\DS\Linear\Vector;
use Exception;
abstract class AbstractOneDimArray
{
/**
*
* @var int
*/
protected /*int*/ $_size = 0;
/**
*
* @var array
*/
protected /*array*/ $_values = [];
protected abstract function getValueType() : string;
protected abstract function getDefaultValue();
public function __construct(int $size)
{
if ($size < 0)
throw new Exception('Size must be positive number.');
$this->_size = $size;
$defaultValue = $this->getDefaultValue();
if (gettype($defaultValue) != $this->getValueType())
throw new Exception('Return type of the getDefaultValue() does not match getValueType().');
for ($i = 0; $i < $this->_size; $i++)
$this->_values[$i] = $defaultValue;
}
public function Size() : int
{
return $this->_size;
}
public function Set(int $index, $value)
{
if ($index < 0 || $index >= $this->_size)
throw new Exception('The index must be in the range (0, ' . ($this->_size -1) . ')');
if (gettype($value) != $this->getValueType())
throw new Exception('The value must be of type ' . $this->getValueType());
$this->_values[$index] = $value;
}
public function Get(int $index)
{
if ($index < 0 || $index >= $this->_size)
throw new Exception('The index must be in the range (0, ' . ($this->_size -1) . ')');
return $this->_values[$index];
}
}
class IntOneDimArray extends AbstractOneDimArray
{
protected function getValueType() : string
{
return gettype(0);
}
protected function getDefaultValue()
{
return 0;
}
}
$size = 5;
$intArray = new IntOneDimArray($size);
for ($i = 0; $i < $intArray->Size(); $i++) {
echo $intArray->Get($i) . ', ';
}
echo PHP_EOL;
for ($i = 0; $i < $intArray->Size(); $i++) {
$intArray->Set($i, $i);
}
for ($i = 0; $i < $intArray->Size(); $i++) {
echo $intArray->Get($i) . ', ';
}
echo PHP_EOL;
echo $intArray->Get($size);