如何用std::valarray和std::gslice替换矩阵第1、3、6列的值
用std::valarray替换矩阵第1、3、6列为-1的实现方式
因为你要修改的三列(第1、3、6列,对应索引0、2、5)之间的间隔不固定,单个std::gslice无法满足需求(gslice要求各维度步长一致),这里提供两种简单可行的方案:
方案一:分三次用std::slice赋值
这是最直观的方式,每一列用一个std::slice定位,分别赋值:
std::valarray<int> va{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}; // 第1列(索引0):起始位置0,共4个元素(4行),步长6(每行6个元素,下一行同列索引+6) va[std::slice(0, 4, 6)] = -1; // 第3列(索引2):起始位置2,同样4个元素,步长6 va[std::slice(2, 4, 6)] = -1; // 第6列(索引5):起始位置5,同样4个元素,步长6 va[std::slice(5, 4, 6)] = -1;
执行后矩阵结果:
-1 2 -1 4 5 -1 -1 8 -1 10 11 -1 -1 14 -1 16 17 -1 -1 20 -1 22 23 -1
方案二:用掩码数组一次性赋值
如果想一次性完成修改,可以先创建掩码标记需要修改的位置,再批量赋值:
std::valarray<int> va{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}; // 创建和va同大小的掩码,默认全部为false std::valarray<bool> mask(va.size(), false); // 标记第1列 mask[std::slice(0, 4, 6)] = true; // 标记第3列 mask[std::slice(2, 4, 6)] = true; // 标记第6列 mask[std::slice(5, 4, 6)] = true; // 批量替换所有标记为true的位置 va[mask] = -1;
为什么原来的std::gslice不适用?
你之前用的std::gslice{0, {2,4}, {2,6}},其中第二个参数{2,4}表示“2列,4行”,第三个参数{2,6}表示“列之间步长2,行之间步长6”。但第3列到第6列的步长是3(索引2→5),和前两列的步长2不一致,无法用单个gslice的统一步长来覆盖这三列,所以得换用上述方法。
内容的提问来源于stack exchange,提问作者Yury
相关产品推荐
相关产品推荐

