matrixarray
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8

Thread: matrixarray

  1. #1
    Join Date
    Mar 2010
    Location
    Melbourne Australia
    Posts
    454

    matrixarray

    I wish to convert a 2D Array i.e int a[20][20] , convert to either s single array as in in[400] or hold it in a vector , and then back again , any ideas ?
    my initial thoughts were

    Code:
    for(a to 200)
    for(b to 200)
    {
      vector.push.back(int[a][b]); // this in sudo code ;
    }

  2. #2
    Join Date
    Apr 1999
    Posts
    27,431

    Re: matrixarray

    Quote Originally Posted by aamir121a View Post
    I wish to convert a 2D Array i.e int a[20][20] , convert to either s single array as in in[400] or hold it in a vector , and then back again , any ideas ?
    Code:
    #include <algorithm>
    #include <vector>
    
    template <typename T>
    struct VectorFrom2DArrayInitializer
    {
        typedef std::vector<T> TVector;
        TVector & m_v;
        int m_nElements;
    
        VectorFrom2DArrayInitializer(TVector& theVector, int numElements) : 
                    m_v(theVector), m_nElements(numElements) {}
    
        void operator()(T *pElements) 
        {   m_v.insert(m_v.end(), pElements, pElements + m_nElements); }
    };
    
    template <typename T, int Rows, int Cols>
    void Init1DVectorFrom2DArray(std::vector<T>& v, T arr[Rows][Cols])
    { std::for_each(arr, arr + Rows, VectorFrom2DArrayInitializer<T>(v, Cols)); }
    
    int main()
    {
        // Initialize array to something
        int a[20][20];
        int counter = 0;
        for (int i = 0; i < 20; ++i)
            for (int j = 0; j < 20; ++j)
                a[i][j] = counter++;
    
        // set vector to the above array
        std::vector<int> v;
        Init1DVectorFrom2DArray<int, 20, 20>(v, a);
    }
    Well, this uses no loops except for the initializer for the array at the beginning of the test main() program.

    It now doesn't matter if it's a 2d array of int, char, double, or Widgets. The 2d array of T is copied to the 1d vector of T using for_each() and a function object. Note that the only reliance on "int" is in the template argument to the Init1DVectorFrom2DArray function. Then everything there relies on type T, regardless of what T is.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; December 2nd, 2012 at 02:13 AM.

  3. #3
    Join Date
    May 2009
    Posts
    2,413

    Re: matrixarray

    Quote Originally Posted by aamir121a View Post
    , any ideas ?
    Instead of copying the arrays you can "overlay" them using a union,

    Code:
    union Same {
       int a[50];
       int b[10][5];
    };
    Here a and b represent the same 50 consecutive ints of memory, only they are accessed according to different matrix abstractions (and more can be added).

    Code:
    Same same; // static allocation at compile time
    //
    same.b[2][3] = 42;
    std::cout << same.a[13] << std::endl;
    It works because b[2][3] and a[13] represent the same memory position (2*5 + 3 = 13).

    Since std::vector allocates memory dynamically a pointer must be used in that case. The above becomes,

    Code:
    std::vector<int> v(50); // dynamic allocation at runtime
    Same* same = reinterpret_cast<Same*>(&v[0]); // sets Same pointer to start of vector data
    //
    same->b[2][3] = 42;
    std::cout << same->a[13] << std::endl;
    std::cout << v[13] << std::endl;
    Last edited by nuzzle; December 3rd, 2012 at 05:00 AM.

  4. #4
    Join Date
    Mar 2010
    Location
    Melbourne Australia
    Posts
    454

    Re: matrixarray

    thank you

  5. #5
    Join Date
    Oct 2008
    Posts
    1,137

    Re: matrixarray

    Quote Originally Posted by nuzzle View Post
    they are accessed according to different matrix abstractions (and more can be added).
    I think this is not advisable; that use of unions relies on specific guarantees related to not-so-manifest properties of the types involved. Even with POD's you have to make sure that those member types have the same memory layout. Yes, with C++11 things have been relaxed to allow standard memory layout types with compatible layouts ( so, say, you could put there an std::array ) but it's still non trivial to check that the code is actually portable. So, I'd leave this technique to implementation details only.

  6. #6
    Join Date
    May 2009
    Posts
    2,413

    Re: matrixarray

    Quote Originally Posted by superbonzo View Post
    So, I'd leave this technique to implementation details only.
    With different matrix abstractions I meant variations of 50 consecutive ints, like say

    Code:
    union Same {
       int a[50];
       int b[10][5];
       int c[25][2];
       int d[2][5][5];
    // etcetera
    };
    To the best of my knowledge my suggestion is portable according to the C++ 11 standard (both regarding memory layout and the use of the reinterpret_cast).

    But I agree that C-ish stuff like this shouldn't be all over the place in a C++ program.

  7. #7
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    3,926

    Re: matrixarray

    alternatvively... "why does it matter" ?
    The data will ultimately be stored similarly, why does your code need to make a difference between 2D (or xD for that matter) or flat (1D) ?

    If you have a need for a container that allows your data to be approached "flat" as well as 2d or 3d, then why not simply make a container like that. Make a template class that takes 2 dimentions, use it to make a X*Y vector, then provide members that can access the data either flat (with 1 index) or as a 2D array (with 2 indexes) (or as a 3D, 4D..... whatever).

  8. #8
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,725

    Re: matrixarray

    Quote Originally Posted by OReubens View Post
    If you have a need for a container that allows your data to be approached "flat" as well as 2d or 3d, then why not simply make a container like that.
    Yes, that's the way I'd approach it.
    "It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
    Richard P. Feynman

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center