1

I have a simple C++ code as below. I need to do a specific task for n dimensions. But the value of n i will get only during runt-time. How can i adpat the code to n dimesnions with vectors at run-time.

    //one dimesion
    std::vector<int> a;
    // do some task with a;

   // two dimension
    std::vector< std::vector<int> > a;
    // do some task with a;
    .
    .

Thanks

codebug
  • 11
  • 1
  • 1
    Wrap vector in your own type that will know the dimension and index accordingly. – Borgleader Dec 06 '14 at 15:50
  • You need to make an n-dimensional array. This is not easy, but you can take a look at my answer here and the corresponding question for some inspiration. http://stackoverflow.com/a/26665964/2159051 – BWG Dec 06 '14 at 15:51
  • @Borgleader thanks for the reply. Can u gimme some tips or links where i can easily understand this wrapping. I am new to C++ – codebug Dec 06 '14 at 15:52
  • Do you want to create an n-dimensional vector where n is defined at runtime ? Or do you want to make an algorithm generic so that it could be exectued regardless the number of dimensions you have ? – Christophe Dec 06 '14 at 15:53
  • @Christophe yes you are right.... I want a generic algoirthm that works for any dimension – codebug Dec 06 '14 at 15:56
  • If dimension of any of your vector is defined at compile time, then, couldn't you simply templatize your algorithm (for example with recursion on dimention) ? – Christophe Dec 06 '14 at 16:05
  • `vector>` is an OK choice for your problem, where the length of the outer vector is your dimension. In the one dimensional case the outer vector simply has a length of `1`. Be aware that this might not be as fast as a smart implementation like bibekdahal is proposing, it will be good enough for most cases though. – pmr Dec 06 '14 at 16:30

2 Answers2

0

You can implement an n-dimensional array using a single vector.

This works like this:

Say your array(A[s1]) is one dimensional. Then array element is accessed like A[i1].

If your array is two dimensional(A[s1][s2]), elements A[0][0] to A[0][s2-1] are stored first and then A[1][0] to A[1][s2-1] follows. Note that all elements are stored in sequentially in single vector. So array element is accessed like A[ i1*s2 + i2 ].

For three dimensional array A[s1][s2][s3], you can think of it as s1-number of two dimensional arrays. the two-dimensional array at A[0] is stored first, then next two dimensional array at A[1] is stored and so on. So element can be accessed using A[ i1*s2*s3 + i2*s3 + i3].

An array with 'n' dimensions, can have its element accessed at [i1][i2][i3]...[in] as:

my_vector[ i1*(s2*s3*...*sn) + i2*(s3*s4*...*sn) + i3*(s4*...*sn) + ... + in ]

where s1, s2, s3, ..., sn are sizes of 1st, 2nd, ..., n-th dimension respectively.

bibekdahal
  • 74
  • 1
  • 4
0

If you want to define a generic algorithm on multidimensional vectors without knowing their dimension (see comments to the question), youd could proceed with a recursive template as in the following simple example:

template <typename T>
void myalgo(T v)       // generic algorithm 
{
    myalgo_imp(v, static_cast<T*>(0));  // trick to distinguish vectors from non vectors
}

template <typename T>
void myalgo_imp(vector<T> cplx, vector<T> *)   // vector implementation
{
    for (T x : cplx)          // Reaply the generic algorithm to the dimension less 1 
        myalgo (x);
}

template <typename T >
void myalgo_imp(T base, T*)   // Apply the generic algorithm for base class (non vector) 
{
    cout << base << endl;
}

The trick with the static cast is explained in this SO question:
You could then use the algorithm as you've requested:

//one dimesion
std::vector<int> a(3);
myalgo(a); 

// two dimension
std::vector< std::vector<int> > aa(3, vector<int>(2,1));
myalgo(aa);

This example is suitable, for example if you want to perform a base task on every base element of your multidimensional vector. Not knowing how your algorithm processes the vector, it's difficult to give a more tailored adaptation of this technique.

Community
  • 1
  • 1
Christophe
  • 68,716
  • 7
  • 72
  • 138