我有一个应该像缓冲区一样的整数矩阵:
x = {{0, 0, 0, 0, 0}, {1, 1, 1, 1, 1}, {2, 2, 2, 2, 2}};
现在,如果我添加一个新行{3, 3, 3, 3, 3}
,新矩阵应该如下所示:
x = {{1, 1, 1, 1, 1}, {2, 2, 2, 2, 2}, {3, 3, 3, 3, 3}};
有没有一种巧妙的方法可以在不复制所有元素的情况下做到这一点?
如果您的矩阵被定义为一个int **
并且您分别分配每一行,那么您只需要交换行指针。
模运算怎么样?
如果您访问元素,matrix[x + SZ * y]
您可以将其更改为:
matrix[x + SZ * ((y + FIRST_ROW) % SZ)]
.
通过这种方式来实现这种转变,您只需将新行 {3, 3, 3..} 放在行 {0, 0, 0} 所在的位置,然后递增FIRST_ROW
计数器以指向新的起始行。
使用链表。
struct node
{
int row[5];
struct node *next;
};
追加一行就像将列表遍历到末尾一样简单,然后将 NULL 下一个指针替换为一个新节点(其下一个指针为 NULL)。
你可以递增x
使它指向第二行,然后释放第一行吗?显然,您需要一次分配一行,这不能保证矩阵是连续的。如果你需要,你可以分配一大块内存来保存你的矩阵,然后在你到达终点时破坏未使用的部分。
如果使用指向数组的指针数组(而不是普通的二维数组),则可以只复制指向行的指针,而不是复制所有元素。
如果您对过度分配指针数组感到满意,您可以在末尾添加一个新指针并将指针推进到数组的“开始”。但是,如果您可能想要多次进行这种转变,这不是一个好主意。当然,您要确保在某处拥有原始指针,以便您可以正确使用free()
资源。
懒于编写代码示例 - 您可以使用模算术来处理行。推新行时,只需增加一个起始偏移变量,加上矩阵高度并以矩阵高度取模。这样您就可以得到一个圆形矩阵,而无需复制整个矩阵并保持矩阵数组紧凑。