1

I was trying to create some vector with negative index but just learnt that it was not allowed in C++. Is there any alternative or better way to do it?

for example I want to create a 3D vector named Wt:

in VBA context array was like built like this: easy and nice

Redim Wt(0 to k_max,-i_max to i_max,-j_max to j_max)
' and use it like below for example: 
Wt(3, -100, -105) = .....

in C++ context it was unfriendly and inconvenient:

// resizing the vector:
Wt.resize(k_max + 1);
for (int k = 0; k < k_max + 1; k++) {
    Wt[k].resize(2 * i_max + 1);
    for (int i = 0; i < 2 * i_max + 1; i++) {
        Wt[k][i].resize(2 * j_max + 1);
    }
}

// when using the vector:
for (int k = 0; k <= k_max; k++) {
    for (int i = -i_max; i <= i_max; i++) {
        for (int j = -j_max; j <= j_max; j++) {
            Wt[k][i + i_max][j + j_max] = ...
        }
    }
}
Tsui John
  • 107
  • 3
  • 21
  • 1
    What is the meaning of the negative index? – Alex Mar 26 '17 at 09:03
  • 5
    Typically you write a class that encapsulates the unfriendly and inconvenient functions and gives you the interface you want. – nwp Mar 26 '17 at 09:06
  • 1
    Possible duplicate of [Are negative array indexes allowed in C?](http://stackoverflow.com/questions/3473675/are-negative-array-indexes-allowed-in-c) – Iman Nia Mar 26 '17 at 09:12
  • @Alex: I mean vector like e.g. Wt[-1][-5][-100] = 1.235 , where index -1, -5, -100 are all negative numbers... – Tsui John Mar 26 '17 at 11:28
  • @TsuiJohn I exactly ask you if you have matrix what is the meaning of negative index? What does it point to? – Alex Mar 26 '17 at 11:30
  • @Alex: thanks I see what you mean. Negative index k, i, j in Wt[k][i][j] is related to stock price movement. i = -5 means stock i moved down by 5 times. My program will receive the (k, i, j) value from some other source and then retrieve the corresponding value from Wt[]. More importantly the size of Wt[k][i][j] will change periodically (but not the stock price movement index) therefore it is very inconvenient forcing me to work with matrix with only positive index allowed. – Tsui John Mar 26 '17 at 13:54

1 Answers1

2

No, you need to shift the index yourself or implement a class that shifts it for you. Here is the code if you need it

#include <iostream>
#include<vector>
#include <stdexcept>
using namespace std;


class FriendlyArray{
    int _maxIndex;
    int _minIndex;
    vector<int> _data;
    public:
        FriendlyArray(int minIndex, int maxIndex)
        {
            _maxIndex=maxIndex;
            _minIndex=minIndex;
            _data=vector<int>(_maxIndex-_minIndex+1);
        }
    public:
      int& operator[] (int x) {
          if (x<_minIndex || x> _maxIndex)
            throw std::logic_error( "Exception example" ); 
          else {
              return _data[x-_minIndex];
          }
      } 
};

int main() {
    FriendlyArray example(-1,11);
    example[-1]=4;
    cout<<example[-1]<<endl;
    // your code goes here
    return 0;
}

Output: 4, as expected

If you want a more generalized version you get

#include <iostream>
#include<vector>
#include <stdexcept>
#include <assert.h>
using namespace std;


template<typename T> class FriendlyArray{
    const int _maxIndex;
    const int _minIndex;
    vector<T> _data;
    public:
        FriendlyArray(int minIndex, int maxIndex):
        _minIndex(minIndex),
        _maxIndex(maxIndex)
        {
            _data=vector<T>(_maxIndex-_minIndex+1);
        }
    public:
      T& operator[] (int x){
          assert(!(x<_minIndex || x> _maxIndex));
          return _data[x-_minIndex];
      } 
};

int main() {
    FriendlyArray<int> example(-1,11);
    example[-1]=4;
    cout<<example[-1]<<endl;

    FriendlyArray<double> example2(-2,20);
    example2[-2]=0.5;
    cout<<example2[-2];
    return 0;
}

Output (as expected): 4 0.5

Gabriel
  • 3,564
  • 1
  • 27
  • 49
  • 1
    Good idea, but the execution has some mistakes. Avoid `using namespace std`, and use an initialisation list instead of assignments. Some nice-to-haves that might have been included: a `const` overload of `operator[]` and perhaps a template argument instead of hard-coding `int`. Personally, I'd also `assert` instead of throw. On the plus side, you use `int` for indices instead of an unsigned type. – Christian Hackl Mar 26 '17 at 11:04
  • ok, will do. I wanted to show the idea by avoiding templates, even though that is more flexible – Gabriel Mar 26 '17 at 11:35
  • Note that any compiler that supports flexible indices in arrays does, internally, translate the index. So the ultimate code will be more or less the same. – Mats Petersson Mar 26 '17 at 11:38
  • Also for multi-dimension array, what was the syntax for assignment operator? Can we use int operator[]= (int x, int y) to represent assign certain value to Wt[k][i][j] e.g. = 1.1234? – Tsui John Mar 26 '17 at 15:43
  • 1
    multidimensional is not a problem as you allocate arrays of arrays, just like before – Gabriel Mar 26 '17 at 17:26