Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C: clever way to "shift" a matrix?

Tags:

c

matrix

shift

I have an integer matrix that should act like a buffer:

x = {{0, 0, 0, 0, 0}, {1, 1, 1, 1, 1}, {2, 2, 2, 2, 2}};

Now if I add a new row {3, 3, 3, 3, 3}, the new matrix should look like:

x = {{1, 1, 1, 1, 1}, {2, 2, 2, 2, 2}, {3, 3, 3, 3, 3}};

Is there a clever way of doing this without copying all elements around?

like image 436
fi_34k7 Avatar asked Nov 02 '10 13:11

fi_34k7


4 Answers

If your matrix is defined as an int ** and you separately allocate each row, then you would only have to swap the row pointers.

like image 56
mikerobi Avatar answered Nov 11 '22 17:11

mikerobi


How about modulo operation?

If you access the elements as matrix[x + SZ * y] you could change it to:

matrix[x + SZ * ((y + FIRST_ROW) % SZ)] .

In this way to implement this shift you just put the new line {3, 3, 3..} where line {0, 0, 0} was, and increment the FIRST_ROW counter to point to the new starting row.

like image 22
ruslik Avatar answered Nov 11 '22 18:11

ruslik


Use a linked list.

struct node
{
    int row[5];
    struct node *next;
};

Appending a row is as simple as walking the list to the end, then replacing the NULL next pointer with a new node (whose next pointer is NULL).

like image 1
nmichaels Avatar answered Nov 11 '22 16:11

nmichaels


Can you increment x so that it points to the second row, then free the first row? Obviously, you would need to allocate a row at a time and this would not guarantee that the matrix is contiguous. If you require that, you could allocate one big block of memory to hold your matrix and then clobber the unused parts when you reach the end.

like image 1
Matt K Avatar answered Nov 11 '22 17:11

Matt K