SORU
8 Ocak 2014, ÇARŞAMBA


Birden fazla yazma '' döngüler temiz yollar

Çok boyutlu bir dizi için, genellikle boyutları her biri için for bir döngü yazmak gerekiyor. Örneğin:

vector< vector< vector<int> > > A;

for (int k=0; k<A.size(); k  )
{
    for (int i=0; i<A[k].size(); i  )
    {
        for (int j=0; j<A[k][i].size(); j  )
        {
            do_something_on_A(A[k][i][j]);
        }
    }
}

double B[10][8][5];
for (int k=0; k<10; k  )
{
    for (int i=0; i<8; i  )
    {
        for (int j=0; j<5; j  )
        {
            do_something_on_B(B[k][i][j]);
        }
    }
}

Kodumuzu sık for-for-for döngüler bu tür bakın. Nasıl yeniden yazma kodu bu tür her zaman için ihtiyacım yok o yüzden makrolar for-for-for döngü tanımlamak için kullanılır? Daha iyi bir yolu bunu yapmak için vardır?

CEVAP
8 Ocak 2014, ÇARŞAMBA


İlk iş böyle bir veri yapısı kullanmak kalmamasıdır. Eğer üç boyutlu matris tanımlamak olmalıdır:

class Matrix3D
{
    int x;
    int y;
    int z;
    std::vector<int> myData;
public:
    //  ...
    int& operator()( int i, int j, int k )
    {
        return myData[ ((i * y)   j) * z   k ];
    }
};

Ya eğer dizin kullanmak istiyorsanız [][][], operator[] bir proxy verir.

Eğer sürekli varsa bu işi buldum. takdim ettik, bir yineleyici seni ifşa yineleme olacak destek:

class Matrix3D
{
    //  as above...
    typedef std::vector<int>::iterator iterator;
    iterator begin() { return myData.begin(); }
    iterator end()   { return myData.end();   }
};

O zaman sen sadece yaz:

for ( Matrix3D::iterator iter = m.begin(); iter != m.end();    iter ) {
    //  ...
}

(ya da sadece:

for ( auto& elem: m ) {
}

C 11.)

Ve eğer bu yineleme sırasında üç dizinler ihtiyacınız varsa, mümkün onları açığa çıkaran bir yineleyici oluşturmak için:

class Matrix3D
{
    //  ...
    class iterator : private std::vector<int>::iterator
    {
        Matrix3D const* owner;
    public:
        iterator( Matrix3D const* owner,
                  std::vector<int>::iterator iter )
            : std::vector<int>::iterator( iter )
            , owner( owner )
        {
        }
        using std::vector<int>::iterator::operator  ;
        //  and so on for all of the iterator operations...
        int i() const
        {
            ((*this) -  owner->myData.begin()) / (owner->y * owner->z);
        }
        //  ...
    };
};

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • FUNKER530 - Veteran Community & Combat Footage

    FUNKER530 -

    25 Ocak 2007
  • Peyton

    Peyton

    28 Aralık 2008
  • Santozz Yazz

    Santozz Yazz

    23 Mart 2014