简体   繁体   中英

Swap columns in c++

I have an std matrix defined as:

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

and a vector v that is:

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

I would like to swap the columns 3 and 2 of matrix Qe like indicated in vector v.

In Matlab this is as easy as writing Qe=Qe(:,v);

I wonder if there is an easy way other than a for loop to do this in c++.

Thanks in advance.

Given that you've implemented this as a vector of vectors, you can use a simple swap:

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

This should have constant complexity. Of course, this will depend on whether you're treating your data as column-major or row-major. If you're going to be swapping columns often, however, you'll want to arrange the data to suit that (ie, to allow the code above to work).

As far as doing the job without a for loop when you're using row-major ordering (the usual for C++), you can technically eliminate the for loop (at least from your source code) by using a standard algorithm instead:

std::for_each(Qe.begin(), Qe.end(), [](std::vector<double> &v) {std::swap(v[2], v[3]); });

This doesn't really change what's actually happening though--it just hides the for loop itself inside a standard algorithm. In this case, I'd probably prefer a range-based for loop:

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

...but I've never been particularly fond of std::for_each , and when C++11 added range-based for loops, I think that was a superior alternative to the vast majority of cases where std::for_each might previously have been a reasonable possibility (IOW, I've never seen much use for std::for_each , and see almost none now).

Depends on how you implement your matrix.

  • If you have a vector of columns, you can swap the column references. O(1)
  • If you have a vector of rows, you need to swap the elements inside each row using a for loop. O(n)

std::vector<std::vector<double>> can be used as a matrix but you also need to define for yourself whether it is a vector of columns or vector of rows .

You can create a function for this so you don't write a for loop each time. For example, you can write a function which receives a matrix which is a vector of columns and a reordering vector (like v) and based on the reordering vector you create a new matrix.

//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;
}

Edit: If you want to do linear algebra there are libraries that can help you, you don't need to write everything yourself. There are math libraries for other purposes too.

If you are in a row scenario. The following would probably work:

// 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]);
}

In this scenario I don't see any other solution that would avoid doing a loop O(n).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM