在C++中交换列

4

我有一个定义为std的矩阵:

std::vector<std::vector<double> > Qe(6,std::vector<double>(6));

并且有一个向量 v,它是:

v{0, 1, 3, 2, 4, 5};

我想按照向量v的指示交换矩阵Qe的第3列和第2列。

在Matlab中,只需编写Qe=Qe(:,v);即可轻松完成。

我想知道除了使用for循环之外,在c++中是否有其他简单的方法可以做到这一点。

提前致谢。


Matlab专门用于这种计算;C++的“vector”是低级原语。换句话说,我不知道有什么比这更低级的了。 - Bartek Banachewicz
你的矩阵是行优先还是列优先?也就是说,Qe[0] 是第一行还是第一列?希望是列,因为那样更容易;-) - Steve Jessop
不,列并不存在。你只有一个向量的向量。你需要实现自己的列交换函数。我也会实现一个真正的矩阵类。 - juanchopanza
嗨,@SteveJessop。恐怕它是行主序的 :( - Noname
@Ceren:是的,那你就完全自己了。 - Steve Jessop
3个回答

3
鉴于您已将其实现为一组向量,因此可以使用简单的交换: ```

鉴于您已将其实现为一组向量,因此可以使用简单的交换:

```
std::swap(Qe[2], Qe[3]);

这应该具有恒定的复杂度。当然,这将取决于您是将数据视为列优先还是行优先。但是,如果您经常交换列,则需要安排数据以适应此操作(即允许上述代码工作)。
至于在使用行优先排序时(通常用于C++),如果要消除for循环(至少从源代码中),您可以在使用标准算法时实现:
std::for_each(Qe.begin(), Qe.end(), [](std::vector<double> &v) {std::swap(v[2], v[3]); });

然而,这并不会改变实际发生的事情--它只是将for循环本身隐藏在一个标准算法内。在这种情况下,我可能更喜欢使用基于范围的for循环:

for (auto &v : Qe) 
    std::swap(v[2], v[3]);

...但我从未特别喜欢std::for_each,当C++11添加基于范围的for循环时,我认为它是绝大多数情况下std::for_each的优秀替代品(也就是说,我以前从未见过太多使用std::for_each的情况,现在几乎没有了)。


由于我将矩阵定义为行主序,这交换了我的第二行和第三行。但无论如何这很有用,谢谢。 - Noname

1
取决于您如何实现矩阵。
  • 如果您有一列向量,则可以交换列引用。 O(1)
  • 如果您有一行向量,则需要使用for循环交换每行内的元素。 O(n)
std :: vector > 可用作矩阵,但您还需要自己定义它是列的向量还是行的向量。
您可以创建一个函数来完成此操作,以便每次不必编写for循环。例如,您可以编写一个接收矩阵(即列向量)和重新排序向量(如v)的函数,并基于重新排序向量创建新矩阵。
//untested code and inefficient, just an example:
vector<vector<double>> ReorderColumns(vector<vector<double>> A, vector<int> order)
{
    vector<vector<double>> B;
    for (int i=0; i<order.size(); i++)
    {
        B[i] = A[order[i]];
    }
    return B;
}

编辑:如果你想进行线性代数运算,有一些库可以帮助你,你不需要自己编写所有的内容。还有其他用途的数学库。

我想知道除了使用for循环以外,在C++中是否有其他简单的方法可以做到这一点。 - Noname

0
如果你处于行的情况下,以下方法可能适用:
// To be tested
std::vector<std::vector<double> >::iterator it;
for (it = Qe.begin(); it != Qe.end(); ++it)
{
    std::swap((it->second)[2], (it->second)[3]);
}

在这种情况下,我没有看到任何其他解决方案可以避免执行O(n)的循环。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接