Adding a new statement each iteration of a for loop. Queue with 2d arrray

Viewed 105

I am trying to create a stream of numbers through a 2d array kind of like a queue but over 2 dimensions.

The final function will take std::string.

I have written some pretty horrific code.. eventually. I looked for a pattern but the thing that gets me is each time the number moves down the queue it needs another line of code and it has to move into the next element in the array.

I figure once I can do that I can put it in a loop.

so you basically add another line of code each time it adds a new number from the iterator.

intarray[0][0] = *it;
    ++it;
    intarray[0][1] = intarray[0][0];

    intarray[0][0] = *it;
    ++it;
    intarray[0][2] = intarray[0][1];
    intarray[0][1] = intarray[0][0];

    intarray[0][0] = *it;
    ++it;
    intarray[0][3] = intarray[0][2];
    intarray[0][2] = intarray[0][1];
    intarray[0][1] = intarray[0][0];

    intarray[0][0] = *it;
    ++it;
    intarray[0][4] = intarray[0][3];
    intarray[0][3] = intarray[0][2];
    intarray[0][2] = intarray[0][1];
    intarray[0][1] = intarray[0][0];

    intarray[0][0] = *it;
    ++it;
    intarray[0][5] = intarray[0][4];
    intarray[0][4] = intarray[0][3];
    intarray[0][3] = intarray[0][2];
    intarray[0][2] = intarray[0][1];
    intarray[0][1] = intarray[0][0];

    intarray[0][0] = *it;
    ++it;
    intarray[0][6] = intarray[0][5];
    intarray[0][5] = intarray[0][4];
    intarray[0][4] = intarray[0][3];
    intarray[0][3] = intarray[0][2];
    intarray[0][2] = intarray[0][1];
    intarray[0][1] = intarray[0][0];

the numbers go down each time a new number is added from the iterator

1 Answers

I think these nested loops is what you need

auto jj = 1u;
while (!condition)
{
    intarray[0][0] = *it;
    ++it;
    for (auto ii=jj; ii >= 1 ; --ii)
        intarray[0][ii] = intarray[0][ii-1];
    ++jj;
}

where condition is whatever condition when you need to stop the process.
This code is not very efficient, though.


EDIT
As I understand you need to use both dimensions, so you have options:
a) if you know the size of your data beforehand, and I think it is the case, since you use statically allocated intarray[N][M]:

for (auto kk=N-1; 0 <= kk; --kk)
    for (auto ii=M-1; 0 <= ii ; --ii)
        {
            intarray[kk][ii] = *it;
            ++it;
        }

you simply fill the array in reverse order, and there is no need to overwrite values many times.

b) if you don't know the size beforehand, but have enough memory (and time): populate dynamically-sized container (I'd recommend std::vector<int>) with data and go route a)

c) if you don't know the size beforehand and don't have enough memory to hold temporary container, you are not able to use statically allocated array. The only solution I see is to populate an std::vector<T> with data, and then write a wrapper function to get the elements in right order.


EDIT2: According to the image you posted in the commentary, you need simple wrapper around an array. Disclaimer: I have not tested the code below, nevertheless, it should work, maybe after minor tweaks.

//while you can do it without class, I prefer this way
class MyArray
{
public:
    //push value in the array
    void push_back(const int a)
    {
        //move values using std::memmove as suggested above 
        std::memmove(&(arr[1]),&(arr[0]),2*N - 1);
        //store first element
        arr[0]=a;
    }

    //calculate index in array and return
    int at(const int a, const int b)
    {
        if (0 == a) //first row
            return arr.at(b); //return just the index
        if (1 == a) //second row
            return arr.at(N - 1 - b); //if 
    }
private:
    //dimension of the array
    static const int N = 10;
    //contiguous static array is enough here
    //one can use C-style array, but no point for doing so
    std::array<int, 2*N> arr;
}

//usage
MyArray mArr;

while(!condition)
{
    mArr.push_back(*it);
    std::cout<<mArr.at(1,2)<<std::endl;
}

To 'move the queue' it is handy to use std::memmove, as suggested by Some programmer dude. Since std::memmove operates over contiguous memory, use std::array, std::vector or 1D C-style array instead of 2D C-style array to hold all elements. To get values calculate the right index for it, depending on the row (first or second).

Related