00001
00002
00003 #include "garray.h"
00004 #include <string.h>
00005
00006
00007 int gArray::defaultFmtDigits=3;
00008 short gArrayCollect::iCtrl=0;
00009 gArrayCollect gArrayCollect::myself;
00010
00011
00012
00013 gVector::gVector (unsigned nMax)
00014 : gInt( (int)nMax ),
00015 n( nMax )
00016 {
00017 v = new int[ n+1 ];
00018 ASSERTION(v!=nil,"v!=nil");
00019 v[ 0 ] = 0;
00020 Zero();
00021 }
00022
00023 gVector::gVector (gVector& copy)
00024 : gInt( copy.N() ),
00025 n( copy.N() )
00026 {
00027 unsigned iter;
00028 v = new int[ n+1 ];
00029 ASSERTION(v!=nil,"v!=nil");
00030 for (iter=1; iter<=n; iter++) v[ iter ] = copy.GetNumInt( iter );
00031 }
00032
00033 gVector::~gVector ()
00034 {
00035 Release();
00036 }
00037
00038 char* gVector::Str ()
00039 {
00040
00041 return StrFormat( nil, nil );
00042 }
00043
00044 char* gVector::StrFormat (char* fmtOptions, char* fmtString)
00045 {
00046 static char sBuf[30];
00047 unsigned iter;
00048 unsigned len;
00049 char* strFmtOptions = fmtOptions==nil ? (char*)"%d" : fmtOptions;
00050 char* strFmtString = fmtString==nil ? (char*)"(%s)" : fmtString;
00051
00052 gString sTemp;
00053 for (iter=1; iter<=n; iter++) {
00054 sprintf( sBuf, strFmtOptions, v[iter] );
00055 if ( iter<n ) strcat( sBuf, " " );
00056 sTemp.Add( sBuf );
00057 }
00058 gString sTempCopy( len = (sTemp.Length()+(unsigned)strlen(strFmtString)+20), '\0' );
00059 snprintf( sTempCopy.Str(), len, strFmtString, sTemp.Str() );
00060 sVector = sTempCopy;
00061
00062 return sVector.Str();
00063 }
00064
00065 void gVector::Release ()
00066 {
00067 delete[] v;
00068 v = nil;
00069 }
00070
00071 void gVector::Resize (unsigned nMax)
00072 {
00073 unsigned iter;
00074 gVector vTemp = *this;
00075 Release();
00076 v = new int[ nMax+1 ];
00077 ASSERTION(v!=nil,"v!=nil");
00078 v[ 0 ] = 0;
00079 for (iter=1; iter<=nMax; iter++) {
00080 v[ iter ] = (iter<=n) ? vTemp[ iter ] : 0;
00081 }
00082 n = nMax;
00083 }
00084
00085 void gVector::Set (int iVal)
00086 {
00087 unsigned iter;
00088 for (iter=1; iter<=n; iter++) v[ iter ] = iVal;
00089 }
00090
00091 gVector& gVector::Sort (bool isAscending)
00092 {
00093 unsigned iter, k, iterBest;
00094 int thisBest, aWorse = isAscending ? GetMaxInt() : GetMinInt();
00095 gVector vTemp( n );
00096 ;
00097 vTemp.Set( aWorse );
00098
00099 for (k=1; k<=n; k++) {
00100 iterBest = 0;
00101 thisBest = aWorse;
00102 for (iter=1; isAscending==true && iter<=n; iter++) {
00103 if ( v[iter] < thisBest ) {
00104 thisBest = v[iter];
00105 iterBest = iter;
00106 }
00107 }
00108 for (iter=1; isAscending==false && iter<=n; iter++) {
00109 if ( v[iter] > thisBest ) {
00110 thisBest = v[iter];
00111 iterBest = iter;
00112 }
00113 }
00114 if ( iterBest<=0 ) continue;
00115 v[ iterBest ] = aWorse;
00116 vTemp[ k ] = thisBest;
00117 }
00118
00119 *this = vTemp;
00120 return *this;
00121 }
00122
00123 gVector& gVector::operator= (gVector& copy)
00124 {
00125 unsigned iter;
00126 Release();
00127 n = copy.n;
00128 v = new int[ n+1 ];
00129 ASSERTION(v!=nil,"v!=nil");
00130 v[0] = 0;
00131 for (iter=1; iter<=n; iter++) v[ iter ] = copy.GetNumInt( iter );
00132 return *this;
00133 }
00134
00135 gVector& gVector::operator+ (gVector& copy)
00136 {
00137 unsigned iter;
00138 if ( n!=copy.N() ) {
00139 GARRAY_ANY_LOG( LOG_ERROR, "operator+" );
00140 return *this;
00141 }
00142
00143 gVector* newA = new gVector( n );
00144 gArrayCollect::Self().Garbage( newA );
00145
00146 for (iter=1; iter<=n; iter++) (*newA)[ iter ] = v[ iter ] + copy.GetNumInt( iter );
00147
00148 return *newA;
00149 }
00150
00151 gVector& gVector::operator- (gVector& copy)
00152 {
00153 unsigned iter;
00154 if ( n!=copy.N() ) {
00155 GARRAY_ANY_LOG( LOG_ERROR, "operator+" );
00156 return *this;
00157 }
00158
00159 gVector* newA = new gVector( n );
00160 gArrayCollect::Self().Garbage( newA );
00161
00162 for (iter=1; iter<=n; iter++) (*newA)[ iter ] = v[ iter ] - copy.GetNumInt( iter );
00163
00164 return *newA;
00165 }
00166
00167 gVector& gVector::operator* (gVector& copy)
00168 {
00169 unsigned iter;
00170 int iVal;
00171
00172 if ( n!=copy.N() ) {
00173 GARRAY_ANY_LOG( LOG_ERROR, "operator*" );
00174 return *this;
00175 }
00176
00177 gVector* newA = new gVector( n );
00178 gArrayCollect::Self().Garbage( newA );
00179
00180 for (iter=1; iter<=n; iter++) {
00181 iVal = v[ iter ] * copy.GetNumInt( iter );
00182 (*newA)[ iter ] = iVal;
00183 }
00184
00185 return *newA;
00186 }
00187
00188 int& gVector::operator[] (unsigned idx)
00189 {
00190 ASSERTION(idx>=1,"idx>=1");
00191 ASSERTION(idx<=n,"idx<=n");
00192 return v[ idx ];
00193 }
00194
00195 bool gVector::operator== (gVector& copy)
00196 {
00197 unsigned iter;
00198 if ( n!=copy.N() ) return false;
00199 for (iter=1; iter<=n; iter++) {
00200 if ( v[ iter ] != copy.GetNumInt( iter ) ) return false;
00201 }
00202 return true;
00203 }
00204
00205 bool gVector::operator!= (gVector& copy)
00206 {
00207 return ((*this) == copy)==false;
00208 }
00209
00210 gArray::gArray (unsigned y, unsigned x)
00211 : gInt( y ),
00212 pV( nil )
00213 {
00214 thisNewDim( y, x );
00215 }
00216
00217 gArray::gArray (gArray& copy)
00218 : gInt( copy.GetInt() ),
00219 pV( nil )
00220 {
00221 thisCopyArray( copy );
00222 }
00223
00224 gArray::~gArray ()
00225 {
00226 Release();
00227 }
00228
00229 char* gArray::Str ()
00230 {
00231 unsigned y;
00232
00233 sArray.SetEmpty();
00234 sArray.Add( '[' );
00235 for (y=1; y<=dimY && IsOk()==true; y++) {
00236 sArray.Add( pV[ y ].Str() );
00237 if ( y<dimY ) sArray.Add( ' ' );
00238 }
00239 sArray.Add( ']' );
00240 return sArray.Str();
00241 }
00242
00243 char* gArray::StrFormat (char* fmtOptions, char* fmtString)
00244 {
00245 unsigned y;
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255 static char sBuf[30];
00256 gString sFmtOptions( fmtOptions==nil ? thisFmtOptions( defaultFmtDigits, 'd' ) : fmtOptions );
00257 char* strFmtOptions = sFmtOptions.Str();
00258 char* strFmtString = fmtString==nil ? (char*)"[@|\n|@]\n" : fmtString;
00259 unsigned fmtLen = (unsigned)strlen( strFmtString );
00260 unsigned iter;
00261 bool isSecondFmt = fmtLen>=3 && strFmtString[1]=='|';
00262
00263 for (iter=0; iter<fmtLen; iter++) {
00264 if ( strFmtString[iter]=='F' ) strFmtString[iter] = '\n';
00265 }
00266
00267 sArray.SetEmpty();
00268
00269
00270
00271
00272
00273
00274 for (y=1; y<=dimY; y++) {
00275 if ( isSecondFmt ) {
00276 char endBuf[8];
00277 char* vectorFmtString = strFmtString[1]=='|' ? (char*)"%s" : nil;
00278 endBuf[ 0 ] = y==dimY ? strFmtString[2] : '\0';
00279 endBuf[ 1 ] = 0;
00280 sprintf( sBuf, "%c%s%s",
00281 y==1 ? strFmtString[0] : strFmtString[1],
00282 (*this)[y].StrFormat( strFmtOptions, vectorFmtString ),
00283 endBuf );
00284 sArray.Add( sBuf );
00285 }
00286 else {
00287 if ( y==1 ) {
00288 sprintf( sBuf, "%c%s%c", strFmtString[0], "%s", strFmtString[1]=='@' ? strFmtString[2] : '.' );
00289 }
00290 else {
00291 if ( y==dimY ) {
00292 if ( fmtLen>6 )
00293 sprintf( sBuf, "%c%s%c", strFmtString[4], "%s", strFmtString[6] );
00294 else
00295 sprintf( sBuf, "[%s]", "%s" );
00296 }
00297 else {
00298 sprintf( sBuf, "%c%s%c", fmtLen>2 ? strFmtString[2] : '[', "%s", strFmtString[1]=='@' ? strFmtString[2] : ']' );
00299 }
00300 }
00301 sArray.Add( (*this)[y].StrFormat( strFmtOptions, sBuf ) );
00302 if ( fmtLen>3 ) {
00303 sArray.Add( strFmtString[3] );
00304 }
00305 }
00306 }
00307
00308 return sArray.Str();
00309 }
00310
00311 void gArray::Release ()
00312 {
00313 delete[] pV;
00314 pV = nil;
00315 }
00316
00317 void gArray::Set (int iVal)
00318 {
00319 unsigned y;
00320 if ( IsOk()==false ) return;
00321 for (y=1; y<=dimY; y++) pV[ y ].Set( iVal );
00322 }
00323
00324 void gArray::Set (gVector& iVector)
00325 {
00326 Resize( 1, iVector.N() );
00327 pV[ 1 ] = iVector;
00328 }
00329
00330 void gArray::TransposeMe ()
00331 {
00332 unsigned y, x, newY, newX;
00333
00334 newY = dimX;
00335 newX = dimY;
00336 gArray aTemp( newY, newX );
00337 for (y=1; y<=newY; y++) {
00338 for (x=1; x<=newX; x++) {
00339 aTemp[ y ][ x ] = pV[ x ][ y ];
00340 }
00341 }
00342 *this = aTemp;
00343 }
00344
00345 gArray& gArray::Transpose ()
00346 {
00347 gArray* newA;
00348 newA = new gArray( *this );
00349 gArrayCollect::Self().Garbage( newA );
00350 newA->TransposeMe();
00351 return *newA;
00352 }
00353
00354 gArray& gArray::AddRow (gVector& aV)
00355 {
00356 unsigned y;
00357 gArray newB( dimY+1, dimX );
00358 if ( aV.N()!=dimX ) {
00359 GARRAY_ANY_LOG( LOG_ERROR, "AddRow" );
00360 return *this;
00361 }
00362 for (y=1; y<=dimY; y++) {
00363 newB[y] = (*this)[y];
00364 }
00365 newB[ y ] = aV;
00366 thisCopyArray( newB );
00367 return *this;
00368 }
00369
00370 gArray& gArray::AddEmptyRow (unsigned iter)
00371 {
00372 unsigned aIter;
00373 gVector aV( dimX );
00374 for (aIter=1; aIter<=iter; aIter++) AddRow( aV );
00375 return *this;
00376 }
00377
00378 gArray& gArray::AddColumn (gVector& aV)
00379 {
00380 unsigned y, x, width = aV.N();
00381 gArray newB( dimY, dimX+1 );
00382 if ( width!=dimY ) {
00383 GARRAY_ANY_LOG( LOG_ERROR, "AddColumn" );
00384 return *this;
00385 }
00386 for (y=1; y<=dimY; y++) {
00387 for (x=1; x<=dimX; x++) {
00388 newB[ y ][ x ] = GetNumInt( y, x );
00389 }
00390 newB[ y ][ x ] = aV[ y ];
00391 }
00392 thisCopyArray( newB );
00393 return *this;
00394 }
00395
00396 gArray& gArray::operator= (gArray& copy)
00397 {
00398 thisCopyArray( copy );
00399 return *this;
00400 }
00401
00402 gArray& gArray::AddEmptyColumn (unsigned iter)
00403 {
00404 unsigned aIter;
00405 gVector aV( dimY );
00406 for (aIter=1; aIter<=iter; aIter++) AddColumn( aV );
00407 return *this;
00408 }
00409
00410 gArray& gArray::JoinArrayRight (gArray& copy, bool doForceDim)
00411 {
00412 unsigned y, x, newX = dimX+copy.DimX(), newY = dimY;
00413 ;
00414 if ( doForceDim==false ) {
00415 if ( dimY!=copy.DimY() ) {
00416 GARRAY_ANY_LOG( LOG_ERROR, "JoinArrayRight (wrong dimY)" );
00417 return *this;
00418 }
00419 }
00420 ASSERTION(doForceDim==false,"doForceDim==false: TODO");
00421 ;
00422 gArray* newA = new gArray( newY, newX );
00423 gArrayCollect::Self().Garbage( newA );
00424 ;
00425 for (y=1; y<=newY; y++) {
00426 gVector aV( newX );
00427 for (x=1; x<=dimX && x<=newX; x++) {
00428 aV[ x ] = GetNumInt( y, x );
00429 }
00430 for (unsigned copyX=1; x<=newX; x++) {
00431 aV[ x ] = copy.GetNumInt( y, copyX++ );
00432 }
00433 (*newA)[ y ] = aV;
00434 }
00435 return *newA;
00436 }
00437
00438 gArray& gArray::JoinArrayDown (gArray& copy, bool doForceDim)
00439 {
00440 unsigned y, newX = dimX, newY = dimY + copy.DimY();
00441 ;
00442 if ( doForceDim==false ) {
00443 if ( dimX!=copy.DimX() ) {
00444 GARRAY_ANY_LOG( LOG_ERROR, "JoinArrayDown (wrong dimX)" );
00445 return *this;
00446 }
00447 }
00448 ASSERTION(doForceDim==false,"doForceDim==false: TODO");
00449 ;
00450 gArray* newA = new gArray( newY, newX );
00451 gArrayCollect::Self().Garbage( newA );
00452 ;
00453 for (y=1; y<=dimY; y++) {
00454 (*newA)[ y ] = (*this)[ y ];
00455 }
00456 for (unsigned copyY=1; y<=newY; y++) {
00457 (*newA)[ y ] = copy[ copyY ];
00458 }
00459 return *newA;
00460 }
00461
00462 gArray& gArray::operator+ (gArray& copy)
00463 {
00464 unsigned y;
00465 if ( DimX()!=copy.DimX() ) {
00466 GARRAY_ANY_LOG( LOG_ERROR, "operator+ (DimX!=copy.DimX)" );
00467 return *this;
00468 }
00469 if ( DimY()!=copy.DimY() ) {
00470 GARRAY_ANY_LOG( LOG_ERROR, "operator+ (DimY!=copy.DimY)" );
00471 return *this;
00472 }
00473
00474 gArray* newA = new gArray( dimY, dimX );
00475 gArrayCollect::Self().Garbage( newA );
00476
00477 for (y=1; y<=dimY; y++) {
00478 (*newA)[ y ] = pV[ y ] + copy[ y ];
00479 }
00480
00481 return *newA;
00482 }
00483
00484 gArray& gArray::operator- (gArray& copy)
00485 {
00486 unsigned y;
00487 if ( DimX()!=copy.DimX() ) {
00488 GARRAY_ANY_LOG( LOG_ERROR, "operator- (DimX!=copy.DimX)" );
00489 return *this;
00490 }
00491 if ( DimY()!=copy.DimY() ) {
00492 GARRAY_ANY_LOG( LOG_ERROR, "operator- (DimY!=copy.DimY)" );
00493 return *this;
00494 }
00495
00496 gArray* newA = new gArray( dimY, dimX );
00497 gArrayCollect::Self().Garbage( newA );
00498
00499 for (y=1; y<=dimY; y++) {
00500 (*newA)[ y ] = pV[ y ] - copy[ y ];
00501 }
00502
00503 return *newA;
00504 }
00505
00506 gArray& gArray::operator* (gArray& copy)
00507 {
00508 unsigned newY, newX;
00509 if ( DimX()!=copy.DimY() ) {
00510 GARRAY_ANY_LOG( LOG_ERROR, "operator* (DimX!=copy.DimY)" );
00511 return *this;
00512 }
00513 ;
00514 newY = DimY();
00515 newX = copy.DimX();
00516
00517 gArray* newA = new gArray( newY, newX );
00518 gArrayCollect::Self().Garbage( newA );
00519 ;
00520
00521 return *newA;
00522 }
00523
00524 gArray& gArray::operator| (gArray& copy)
00525 {
00526 return JoinArrayRight( copy, false );
00527 }
00528
00529 gVector& gArray::operator[] (unsigned idx)
00530 {
00531 if ( idx<1 || idx>dimY ) {
00532 GARRAY_ANY_LOG( LOG_ERROR, "operator[] (wrong index)" );
00533 idx = 0;
00534 }
00535 return pV[ idx ];
00536 }
00537
00538 bool gArray::operator== (gArray& copy)
00539 {
00540 unsigned y;
00541 if ( dimY!=copy.DimY() || dimX!=copy.DimX() ) return false;
00542 for (y=1; y<=dimY; y++) {
00543 if ( (pV[ y ]==copy[ y ])==false ) return false;
00544 }
00545 return true;
00546 }
00547
00548 bool gArray::operator!= (gArray& copy)
00549 {
00550 return ((*this) == copy)==false;
00551 }
00552
00553 int gArray::thisNewDim (unsigned y, unsigned x)
00554 {
00555 dimY = y;
00556 dimX = x;
00557 Release();
00558 pV = new gVector[ dimY+1 ];
00559 ASSERTION(pV!=nil,"pV!=nil");
00560 for (y=1; y<=dimY; y++) pV[ y ].Resize( x );
00561 return 0;
00562 }
00563
00564 int gArray::thisCopyArray (gArray& copy)
00565 {
00566 unsigned y;
00567 thisNewDim( copy.DimY(), copy.DimX() );
00568 for (y=1; y<=dimY; y++) {
00569 pV[ y ] = copy[ y ];
00570 }
00571 return 0;
00572 }
00573
00574 char* gArray::thisFmtOptions (int nrFmtDigits, char fmtChar)
00575 {
00576 gString sTemp( 30, '\0' );
00577 snprintf( sTemp.Str(), 30, "%%%d%c", nrFmtDigits, fmtChar );
00578 sArray = sTemp;
00579 return sArray.Str();
00580 }
00581
00582 gArrayCollect::gArrayCollect ()
00583 {
00584 if ( iCtrl==0 ) {
00585 iCtrl = 1;
00586 gStorageControl::Self().StaticAlloc( "gArrayCollect:lGarbage", 1 );
00587 }
00588 }
00589
00590 gArrayCollect::~gArrayCollect ()
00591 {
00592 ReleaseAll();
00593 }
00594
00595 int gArrayCollect::Garbage (gStorage* newA)
00596 {
00597 return thisAddIntoList( newA, lGarbage );
00598 }
00599
00600 int gArrayCollect::ReleaseAll ()
00601 {
00602 lGarbage.Delete();
00603 return 0;
00604 }
00605
00606 int gArrayCollect::thisAddIntoList (gStorage* newA, gList& aList)
00607 {
00608 ASSERTION(newA!=nil,"newA!=nil");
00609 aList.AppendObject( newA );
00610 return 0;
00611 }
00612
00613