矩阵(C++)

  1 /* array.h    2 *  ****** BEGIN LICENSE BLOCK *****
  3 * $Id: arrays.h,v 1.21 2008/03/14 08:17:36 asuraparaju Exp $ $Name: Dirac_1_0_2 $
  4 *
  5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  6 *
  7 * The contents of this file are subject to the Mozilla Public License
  8 * Version 1.1 (the "License"); you may not use this file except in compliance
  9 * with the License. You may obtain a copy of the License at
 10 * http://www.mozilla.org/MPL/
 11 *
 12 * Software distributed under the License is distributed on an "AS IS" basis,
 13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 14 * the specific language governing rights and limitations under the License.
 15 *
 16 * The Original Code is BBC Research and Development code.
 17 *
 18 * The Initial Developer of the Original Code is the British Broadcasting
 19 * Corporation.
 20 * Portions created by the Initial Developer are Copyright (C) 2004.
 21 * All Rights Reserved.
 22 *
 23 * Contributor(s): Thomas Davies (Original Author), 
 24 *                 Peter Meerwald (pmeerw@users.sourceforge.net)
 25 *                 Mike Ferenduros (mike_ferenzduros@users.sourceforge.net)
 26 *                 Anuradha Suraparaju
 27 *
 28 * Alternatively, the contents of this file may be used under the terms of
 29 * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
 30 * Public License Version 2.1 (the "LGPL"), in which case the provisions of
 31 * the GPL or the LGPL are applicable instead of those above. If you wish to
 32 * allow use of your version of this file only under the terms of the either
 33 * the GPL or LGPL and not to allow others to use your version of this file
 34 * under the MPL, indicate your decision by deleting the provisions above
 35 * and replace them with the notice and other provisions required by the GPL
 36 * or LGPL. If you do not delete the provisions above, a recipient may use
 37 * your version of this file under the terms of any one of the MPL, the GPL
 38 * or the LGPL.
 39 * ***** END LICENSE BLOCK ***** */
 40 
 41 #ifndef _ARRAYS_H_
 42 #define _ARRAYS_H_
 43 
 44 //basic array types used for pictures etc
 45 
 46 #include <memory>
 47 #include <cstddef>
 48 #include <stdexcept>
 49 #include <iostream>
 50 #include <algorithm>
 51 #include <cstring>
 52 
 53 namespace dirac
 54 {
 55     //! Range type. 
 56     /*!
 57         Range type encapsulating a closed range of values [first,last]. 
 58         Used to initialies OneDArrays.
 59      */
 60     class Range
 61     {
 62     public:
 63         //! Constructor
 64         /*!
 65             Constructor taking a start and an end point for the range.
 66          */
 67         Range(int s, int e): m_fst(s), m_lst(e){}
 68 
 69         //! Returns the start of the range.
 70         int First() const {return m_fst;}
 71 
 72         //! Returns the end point of the range.
 73         int Last() const {return m_lst;}
 74 
 75         int m_fst ,m_lst;
 76     };
 77 
 78     //////////////////////////////
 79     //One-Dimensional Array type//
 80     //////////////////////////////
 81 
 82     //! A template class for one-dimensional arrays.
 83     /*!
 84         A template class for one-D arrays. Can be used wherever built-in 
 85         arrays are used, and eliminates the need for explicit memory 
 86         (de-)allocation. Also supports arrays not based at zero.
 87      */
 88     template <class T> class OneDArray
 89     {
 90     public:
 91         //! Default constructor.
 92         /*!
 93             Default constructor produces an empty array.
 94          */    
 95         OneDArray();
 96 
 97         //! 'Length' constructor.
 98         /*!
 99             Length constructor produces a zero-based array.
100          */    
101         OneDArray(const int len);
102 
103        //! Range constructor
104         /*!
105             Range constructor produces an array with values indexed within the 
106             range parameters.
107             \param    r    a range of indexing values.
108          */        
109         OneDArray(const Range& r);
110 
111         //! Destructor.
112         /*!
113             Destructor frees the data allocated in the constructors.
114          */
115         ~OneDArray()
116         {
117             FreePtr();
118         }
119 
120         //! Copy constructor.
121         /*!
122             Copy constructor copies both data and metadata.
123          */
124         OneDArray(const OneDArray<T>& cpy);
125 
126         //! Assignment=
127         /*!
128             Assignment= assigns both data and metadata.
129          */
130         OneDArray<T>& operator=(const OneDArray<T>& rhs);    
131 
132         //! Resize the array, throwing away the current data.
133         void Resize(int l);
134 
135         //! Element access.
136         T& operator[](const int pos){return m_ptr[pos-m_first];}
137 
138         //! Element access.
139         const T& operator[](const int pos) const {return m_ptr[pos-m_first];}
140 
141         //! Returns the length of the array.    
142         int Length() const {return m_length;}
143 
144         //! Returns the index of the first element.    
145         int First() const {return m_first;}
146 
147         //! Returns the index of the last element.    
148         int Last() const {return m_last;}
149 
150         void Init(const int len);
151 
152         void Init(const Range& r);
153 
154         void FreePtr();    
155 
156         int m_first, m_last;
157         int m_length;
158         T* m_ptr;
159     };
160 
161     //public member functions//
162     ///////////////////////////
163 
164     template <class T>
165     OneDArray<T>::OneDArray()
166     {
167         Init(0);
168     }
169 
170     template <class T>
171     OneDArray<T>::OneDArray(const int len)
172     {
173         Init(len);
174     }
175 
176     template <class T>
177     OneDArray<T>::OneDArray(const Range& r)
178     {
179         Init(r);
180     }
181 
182     template <class T>
183     OneDArray<T>::OneDArray(const OneDArray<T>& cpy)
184     {
185         m_first = cpy.m_first;
186         m_last = cpy.m_last;
187         m_length = m_last - m_first + 1;
188 
189         if (m_first==0)
190             Init(m_length);
191         else
192             Init(Range(m_first , m_last));
193 
194         memcpy( m_ptr , cpy.m_ptr , m_length * sizeof( T ) );
195     }
196 
197     template <class T>
198     OneDArray<T>& OneDArray<T>::operator=(const OneDArray<T>& rhs)
199     {
200         if (&rhs != this)
201         {
202             FreePtr();
203             m_first = rhs.m_first;
204             m_last = rhs.m_last;
205             m_length = rhs.m_length;
206 
207             if (m_first == 0)
208                 Init(m_length);
209             else
210                 Init(Range(m_first , m_last));
211 
212             memcpy( m_ptr , rhs.m_ptr , m_length * sizeof( T ) );
213 
214         }
215         return *this;
216     }
217 
218     template <class T> 
219     void OneDArray<T>::Resize(int l)
220     {
221         if (l != m_length)
222         {
223             FreePtr();
224             Init(l);
225         }
226     }
227 
228     //private member functions//
229     ////////////////////////////
230 
231     template <class T>
232     void OneDArray<T>::Init(const int len)
233     {
234         Range r(0 , len-1);
235 
236         Init(r);
237 
238     }        
239 
240     template <class T>
241     void OneDArray<T>::Init(const Range& r)
242     {
243 
244         m_first = r.First();
245         m_last = r.Last();
246         m_length = m_last - m_first + 1; 
247 
248         if ( m_length>0 ) 
249         {
250             m_ptr = new T[ m_length ];
251         }
252         else 
253         {
254             m_length = 0;
255             m_first = 0;
256             m_last = -1;
257             m_ptr = NULL;
258         }
259     }
260 
261     template <class T>
262     void OneDArray<T>::FreePtr()
263     {
264         if ( m_length>0 )
265             delete[] m_ptr;
266     }
267 
268 
269     //////////////////////////////
270     //Two-Dimensional Array type//
271     //////////////////////////////
272 
273     //! A template class for two-dimensional arrays.
274     /*!
275         A template class to do two-d arrays, so that explicit memory 
276         (de-)allocation is not required. Only zero-based arrays are 
277         currently supported so that access is fast. Accessing elements along 
278         a row is therefore much faster than accessing them along a column.
279         Rows are contiguous in memory, so array[y][x] is equivalent to
280         array[0][x+y*LengthX()].
281      */
282     template <class T> class TwoDArray
283     {
284         typedef T* element_type;
285 
286     public:
287 
288         //! Default constructor.
289         /*!
290             Default constructor creates an empty array.
291          */    
292         TwoDArray(){ Init(0,0); }
293 
294         //! Constructor.
295         /*!
296             The constructor creates an array of given width height.
297          */    
298         TwoDArray( const int height , const int width ){Init(height , width);}
299 
300         //! Constructor.
301         /*!
302             The constructor creates an array of given width and length height 
303             and initialises it to a value
304          */    
305         TwoDArray( const int height , const int width , T val);
306 
307         //! Destructor
308         /*!
309             Destructor frees the data allocated in the constructor.
310          */    
311         virtual ~TwoDArray(){
312             FreeData();    
313         }
314 
315         //! Copy constructor.
316         /*!
317             Copy constructor copies data and metadata.
318          */    
319         TwoDArray(const TwoDArray<T>& Cpy);
320 
321         //! Assignment =
322         /*!
323             Assignement = assigns both data and metadata.
324          */    
325         TwoDArray<T>& operator=(const TwoDArray<T>& rhs);
326 
327         //! Copy Contents
328         /*!
329             Copy contents of array into output array retaining the dimensions
330             of the output array. If output array is larger that array then
331             pad with last true value.
332             Return true is copy was successful
333          */    
334         bool CopyContents(TwoDArray<T>& out) const;
335 
336         //! Fill contents
337         /*!
338             Initialise the array with the val provided.
339          */    
340         void Fill(T val);
341 
342         //! Resizes the array, deleting the current data.    
343         void Resize(const int height, const int width);    
344 
345         //! Element access.
346         /*!
347             Accesses the rows of the arrays, which are returned in the form 
348             of pointers to the row data NOT OneDArray objects.
349          */    
350         inline element_type& operator[](const int pos){return m_array_of_rows[pos];}
351 
352         //! Element access.
353         /*!
354             Accesses the rows of the arrays, which are returned in the form of 
355             pointers to the row data NOT OneDArray objects.
356          */
357         inline const element_type& operator[](const int pos) const {return m_array_of_rows[pos];}
358 
359         //! Returns the width
360         int LengthX() const { return m_length_x; }
361 
362         //! Returns the height
363         int LengthY() const { return m_length_y; }
364 
365         //! Returns the index of the first element of a row
366         int FirstX() const { return m_first_x; } 
367 
368         //! Returns the index of the first element of a column
369         int FirstY() const { return m_first_y; } 
370 
371         //! Returns the index of the last element of a row
372         int LastX() const { return m_last_x; } 
373 
374         //! Returns the index of the first element of a column
375         int LastY() const { return m_last_y; }
376 
377         //! Initialise the array
378         void Init(const int height,const int width);
379 
380         //! Free all the allocated data
381         void FreeData();    
382 
383         int m_first_x;
384         int m_first_y;
385 
386         int m_last_x;
387         int m_last_y;
388 
389         int m_length_x;
390         int m_length_y;
391 
392         element_type* m_array_of_rows;
393     };
394 
395     //public member functions//
396     ///////////////////////////
397 
398     template <class T>
399     TwoDArray<T>::TwoDArray( const int height , const int width , const T val)
400     {
401         Init( height , width );  
402         std::fill_n( m_array_of_rows[0], m_length_x*m_length_y, val);
403     }  
404 
405     template <class T>
406     TwoDArray<T>::TwoDArray(const TwoDArray<T>& Cpy)
407     {
408         m_first_x = Cpy.m_first_x;
409         m_first_y = Cpy.m_first_y;        
410         m_last_x = Cpy.m_last_x;
411         m_last_y = Cpy.m_last_y;
412 
413         m_length_x = m_last_x - m_first_x + 1;
414         m_length_y = m_last_y - m_first_y + 1;        
415 
416         if (m_first_x == 0 && m_first_y == 0)        
417             Init(m_length_y , m_length_x);
418         else{
419                 //based 2D arrays not yet supported    
420         }
421 
422         memcpy( m_array_of_rows[0] , (Cpy.m_array_of_rows)[0] , m_length_x * m_length_y * sizeof( T ) );
423 
424     }
425 
426     template <class T>
427     TwoDArray<T>& TwoDArray<T>::operator=(const TwoDArray<T>& rhs)
428     {
429         if (&rhs != this)
430         {
431             FreeData();
432 
433             m_first_x = rhs.m_first_x;
434             m_first_y = rhs.m_first_y;            
435 
436             m_last_x = rhs.m_last_x;
437             m_last_y = rhs.m_last_y;
438 
439             m_length_x = m_last_x - m_first_x + 1;
440             m_length_y = m_last_y - m_first_y + 1;        
441 
442             if (m_first_x == 0 && m_first_y == 0)
443                 Init(m_length_y , m_length_x);
444             else
445             {
446                     //based 2D arrays not yet supported
447             }
448 
449             memcpy( m_array_of_rows[0], (rhs.m_array_of_rows)[0], m_length_x * m_length_y * sizeof( T ) );
450 
451         }
452 
453         return *this;
454 
455     }
456     
457     template <class T>
458     bool TwoDArray<T>::CopyContents(TwoDArray<T>& out) const
459     {
460         if (&out != this)
461         {
462             int rows = std::min (m_length_y, out.m_length_y);
463             int cols = std::min (m_length_x, out.m_length_x);
464             for (int j = 0; j < rows; ++j)
465             {
466                 memcpy( out.m_array_of_rows[j], m_array_of_rows[j], cols * sizeof( T )) ;
467                 for (int i = cols; i <out.m_length_x; ++i)
468                     out.m_array_of_rows[j][i] = out.m_array_of_rows[j][cols-1];
469             }
470             for (int j = rows; j < out.m_length_y; ++j)
471             {
472                 memcpy( out.m_array_of_rows[j], out.m_array_of_rows[rows-1], out.m_length_x * sizeof( T )) ;
473             }
474         }
475         return true;
476     }
477     
478     template <class T>
479     void TwoDArray<T>::Fill( T val)
480     {
481         if (m_length_x && m_length_y)
482             std::fill_n( m_array_of_rows[0], m_length_x*m_length_y, val);
483     }  
484 
485     template <class T>
486     void TwoDArray<T>::Resize(const int height, const int width)
487     {
488         if (height != m_length_y || width != m_length_x)
489         {
490             FreeData();
491             Init(height , width);
492         }
493     }
494 
495     //private member functions//
496     ////////////////////////////
497 
498     template <class T>
499     void TwoDArray<T>::Init(const int height , const int width)
500     {
501         m_length_x = width; 
502         m_length_y = height;
503         m_first_x = 0;
504         m_first_y = 0;
505 
506         m_last_x = m_length_x-1;
507         m_last_y = m_length_y-1;
508 
509         if (m_length_y>0)
510         {
511             // allocate the array containing ptrs to all the rows
512             m_array_of_rows = new element_type[ m_length_y ];
513 
514             if ( m_length_x>0 )
515             {
516                 // Allocate the whole thing as a single big block
517                 m_array_of_rows[0] = new T[ m_length_x * m_length_y ];
518 
519                 // Point the pointers
520                 for (int j=1 ; j<m_length_y ; ++j)
521                     m_array_of_rows[j] = m_array_of_rows[0] + j * m_length_x;
522             }
523             else
524             {
525                 m_length_x = 0;
526                 m_first_x = 0;
527                 m_last_x = -1;
528             }
529         }
530         else 
531         {
532             m_length_x = 0;
533             m_length_y = 0;
534             m_first_x = 0;
535             m_first_y = 0;
536             m_last_x = -1;
537             m_last_y = -1;
538             m_array_of_rows = NULL;
539         }
540     }
541 
542     template <class T>
543     void TwoDArray<T>::FreeData()
544     {
545         if (m_length_y>0)
546         {
547             if (m_length_x>0) 
548             {
549                 delete[] m_array_of_rows[0];
550             }
551 
552             m_length_y = m_length_x = 0;
553             // deallocate the array of rows
554             delete[] m_array_of_rows;
555         }    
556     }
557 
558     // Related functions
559 
560     //! A function for extracting array data
561     template <class T >
562     std::ostream & operator<< (std::ostream & stream, TwoDArray<T> & array)
563     {
564         for (int j=0 ; j<array.LengthY() ; ++j)
565         {
566             for (int i=0 ; i<array.LengthX() ; ++i)
567             {
568                 stream << array[j][i] << " ";
569             }// i
570             stream << std::endl;
571         }// j
572 
573         return stream;
574     }
575 
576     //! A function for inserting array data
577     template <class T >
578     std::istream & operator>> (std::istream & stream, TwoDArray<T> & array)
579     {
580         for (int j=0 ; j<array.LengthY() ; ++j)
581         {
582             for (int i=0 ; i<array.LengthX() ; ++i)
583             {
584                 stream >> array[j][i];
585             }// i
586         }// j
587 
588         return stream;
589     }
590 
591 } //namespace dirac
592 #endif

 

 1 // Arrays_Test.cpp
 2 
 3 #include <iostream>
 4 #include "arrays.h"
 5 
 6 using namespace dirac;
 7 using namespace std;
 8 
 9 int main()
10 {
11 // test vector
12 
13 cout <<"******** Test OneDArray ***********" << endl;
14 const int N = 10;
15 OneDArray<int>  a(N);
16 
17 for (int i = 0; i <N; i++)
18     a[i] = i;
19 
20 for (int i = 0; i< N; i++)
21     cout << i <<" ";
22 cout <<endl;
23 
24 const int first = 1;
25 const int last = 10;
26 OneDArray<int>  b(Range(1, 10));
27 for (int i =first; i<= last; i++)
28          b[i] = i;
29 
30 for (int i =first; i<= last; i++)
31          cout << b[i] <<" ";
32 cout <<endl;
33 
34 
35 // test Matrix
36 cout <<"******** Test TwoDArray ***********" << endl;
37 int height = 4;
38 int width = 8;
39 
40 TwoDArray<int> MA(height, width);
41 
42 for (int i = 0; i< height; i++)
43   for (int j = 0; j <width; j++)
44        MA[i][j] = i-j;
45 
46 for (int i = 0; i< height; i++)
47 {
48   for (int j = 0; j <width; j++)
49   {
50        cout << MA[i][j] <<" ";
51   }
52    cout << endl;
53 }
54 
55 
56 TwoDArray<int> MB(height, width, 5);
57 for (int i = 0; i< height; i++)
58 {
59   for (int j = 0; j <width; j++)
60   {
61        cout << MA[i][j] <<" ";
62   }
63    cout << endl;
64 }
65 
66 
67 return 0;
68 }

******** Test OneDArray ***********
0 1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9 10
******** Test TwoDArray ***********
0 -1 -2 -3 -4 -5 -6 -7
1 0 -1 -2 -3 -4 -5 -6
2 1 0 -1 -2 -3 -4 -5
3 2 1 0 -1 -2 -3 -4
******** Test TwoDArray initialized with assigne value***********
5 5 5 5 5 5 5 5
5 5 5 5 5 5 5 5
5 5 5 5 5 5 5 5
5 5 5 5 5 5 5 5

posted @ 2017-03-21 20:07  souwang  阅读(318)  评论(0编辑  收藏  举报