11from pydatastructs .utils .misc_util import _check_type , NoneType
22
33__all__ = [
4- 'OneDimensionalArray' ,
5- 'DynamicOneDimensionalArray'
4+ 'OneDimensionalArray' ,
5+ 'MultiDimensionalArray' ,
6+ 'DynamicOneDimensionalArray'
67]
78
89class Array (object ):
910 '''
1011 Abstract class for arrays in pydatastructs.
1112 '''
12- pass
13+ def __str__ (self ) -> str :
14+ return str (self ._data )
1315
1416class OneDimensionalArray (Array ):
1517 '''
@@ -112,8 +114,7 @@ def __new__(cls, dtype=NoneType, *args, **kwargs):
112114 @classmethod
113115 def methods (cls ):
114116 return ['__new__' , '__getitem__' ,
115- '__setitem__' , 'fill' , '__len__' ,
116- '__str__' ]
117+ '__setitem__' , 'fill' , '__len__' ]
117118
118119 def __getitem__ (self , i ):
119120 if i >= self ._size or i < 0 :
@@ -136,9 +137,125 @@ def fill(self, elem):
136137 def __len__ (self ):
137138 return self ._size
138139
139- def __str__ (self ):
140- return str (self ._data )
140+ class MultiDimensionalArray (Array ):
141+ """
142+ Represents a multi-dimensional array.
143+
144+ Parameters
145+ ==========
146+
147+ dtype: type
148+ A valid object type.
149+ *args: int
150+ The dimensions of the array.
151+
152+ Raises
153+ ======
154+
155+ IndexError
156+ Index goes out of boundaries, or
157+ the number of index given is not
158+ the same as the number of dimensions.
159+ ValueError
160+ When there's no dimensions or the
161+ dimension size is 0.
162+
163+ Examples
164+ ========
165+
166+ >>> from pydatastructs import MultiDimensionalArray as MDA
167+ >>> arr = MDA(int, 5, 6, 9)
168+ >>> arr.fill(32)
169+ >>> arr[3, 0, 0]
170+ 32
171+ >>> arr[3, 0, 0] = 7
172+ >>> arr[3, 0, 0]
173+ 7
174+
175+ References
176+ ==========
177+
178+ .. [1] https://en.wikipedia.org/wiki/Array_data_structure#Multidimensional_arrays
179+
180+ """
181+ __slots__ = ['_sizes' , '_data' , '_dtype' ]
182+
183+ def __new__ (cls , dtype : type = NoneType , * args , ** kwargs ):
184+ if dtype is NoneType or not args :
185+ raise ValueError ("Array cannot be created due to incorrect"
186+ " information." )
187+ if len (args ) == 1 :
188+ obj = Array .__new__ (cls )
189+ obj ._dtype = dtype
190+ obj ._sizes = (args [0 ], 1 )
191+ obj ._data = [None ] * args [0 ]
192+ return obj
193+
194+ dimensions = args
195+ for dimension in dimensions :
196+ if dimension < 1 :
197+ raise ValueError ("Array cannot be created due to incorrect"
198+ " dimensions." )
199+ n_dimensions = len (dimensions )
200+ d_sizes = []
201+ index = 0
202+ while n_dimensions > 1 :
203+ size = dimensions [index ]
204+ for i in range (index + 1 , len (dimensions )):
205+ size = size * dimensions [i ]
206+ d_sizes .append (size )
207+ n_dimensions -= 1
208+ index += 1
209+ d_sizes .append (dimensions [index ])
210+ d_sizes .append (1 )
211+ obj = Array .__new__ (cls )
212+ obj ._dtype = dtype
213+ obj ._sizes = tuple (d_sizes )
214+ obj ._data = [None ] * obj ._sizes [1 ] * dimensions [0 ]
215+ return obj
141216
217+ @classmethod
218+ def methods (cls ) -> list :
219+ return ['__new__' , '__getitem__' , '__setitem__' , 'fill' , 'shape' ]
220+
221+ def __getitem__ (self , indices ):
222+ self ._compare_shape (indices )
223+ if isinstance (indices , int ):
224+ return self ._data [indices ]
225+ position = 0
226+ for i in range (0 , len (indices )):
227+ position += self ._sizes [i + 1 ] * indices [i ]
228+ return self ._data [position ]
229+
230+ def __setitem__ (self , indices , element ) -> None :
231+ self ._compare_shape (indices )
232+ if isinstance (indices , int ):
233+ self ._data [indices ] = element
234+ else :
235+ position = 0
236+ for i in range (0 , len (indices )):
237+ position += self ._sizes [i + 1 ] * indices [i ]
238+ self ._data [position ] = element
239+
240+ def _compare_shape (self , indices ) -> None :
241+ indices = [indices ] if isinstance (indices , int ) else indices
242+ if len (indices ) != len (self ._sizes ) - 1 :
243+ raise IndexError ("Shape mismatch, current shape is %s" % str (self .shape ))
244+ if any (indices [i ] >= self ._sizes [i ] for i in range (len (indices ))):
245+ raise IndexError ("Index out of range." )
246+
247+ def fill (self , element ) -> None :
248+ element = self ._dtype (element )
249+ for i in range (len (self ._data )):
250+ self ._data [i ] = element
251+
252+ @property
253+ def shape (self ) -> tuple :
254+ shape = []
255+ size = len (self ._sizes )
256+ for i in range (1 , size ):
257+ shape .append (self ._sizes [i - 1 ]// self ._sizes [i ])
258+ return tuple (shape )
142259
143260class DynamicArray (Array ):
144261 """
0 commit comments