Thread: Copy vector [need advice]

  1. #1
    Registered User
    Join Date
    Oct 2009
    Posts
    46

    Copy vector [need advice]

    Hi all,

    Is there a better way of copying the lines of 4 two dimension vectors?

    The idea is to copy the contents of line X from v1 to v2, v2 to v3, v3 to v4 and v4 to v1.

    I'm using to two aux variables and then calling std::copy, something like below:

    Code:
    std::vector v1 (3,std::vector<int> >(3,1));
    std::vector v2 (3,std::vector<int> >(3,2));
    ... and so on
    
    std::vector<int> aux0;
    std::vector<int> aux1;
    aux0 = v2[0];
    std::copy(v1[0].begin(),v1[0].end(),v2[0].begin());
    aux1 = v3[0];
    std::copy(aux0.begin(),aux0.end(),v3[0].begin());
    aux0 = v4[0];
    std::copy(aux1.begin(),aux1.end(),v4[0].begin());
    std::copy(aux0.begin(),aux0.end(),v1[0].begin());
    Thanks in advance!

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Copy the contents of v4 to aux0. Now, copy v3 to v4, then v2 to v3, then v1 to v2, then aux0 to v1.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Oct 2009
    Posts
    46
    Ooh. How didn't I think of that. Maybe its time for a break. Thank you laserlight.

  4. #4
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Or perhaps use swap? Swap v1 and v2, v1 and v3, v1 and v4. Now v1 has the contents of v4, v2 has the contents of v1, v3 of v2 and v4 of v3.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by anon View Post
    Or perhaps use swap? Swap v1 and v2, v1 and v3, v1 and v4. Now v1 has the contents of v4, v2 has the contents of v1, v3 of v2 and v4 of v3.
    I'm thinking that's fewer lines of code that you have to write, but more actual work the machine has to do (six copies instead of five). OTOH I have no idea how time-critical the code actually is.

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    hmm... on the other hand, member swap is likely to swap the internal pointers, which would result in quite a gain in efficiency.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    The larch
    Join Date
    May 2006
    Posts
    3,573
    I'm thinking that's fewer lines of code that you have to write, but more actual work the machine has to do (six copies instead of five). OTOH I have no idea how time-critical the code actually is.
    That would both be fewer lines, and much less work, regardless of whether you use the member function or the overload of global swap. swap
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Come to think about it though: why do you have four separate objects named v1, v2, v3 and v4? It seems like you should have say, a std::vector<int>[4], or std::tr1::array<std::vector<int>, 4>. If so, you could use std::rotate, though it would result in full copies rather than a rotation of internal pointers. (On the other hand, you could store a separate array of pointers to the first elements of these vectors, and rotate that instead.)

    EDIT:
    Interestingly, the standard mentions number of swaps when talking about the complexity of std::rotate, but number of assignments when talking about the complexity of std::rotate_copy.
    Last edited by laserlight; 04-23-2010 at 09:34 AM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Hadn't thought about member swap. Using the code:
    Code:
    int main(void) {
    
        std::vector<std::vector<int> > v1(3);
        std::vector<std::vector<int> > v2(3);
        std::vector<std::vector<int> > v3(3);
        std::vector<std::vector<int> > v4(3);
    
        for (int i = 0; i < 3; ++i) {
            for (int j = 0; j < 10000000; ++j) {
                v1[i].push_back(rand());
                v2[i].push_back(rand());
                v3[i].push_back(rand());
                v4[i].push_back(rand());
            }
        }
    
        //We'll move the middle row
        std::vector<int> aux = v4[1];
        v4[1] = v3[1];
        v3[1] = v2[1];
        v2[1] = v1[1];
        v1[1] = aux;
    
        /*std::swap(v1[1], v2[1]);
        std::swap(v1[1], v3[1]);
        std::swap(v1[1], v4[1]);*/
    
        /*v1[1].swap(v2[1]);
        v1[1].swap(v3[1]);
        v1[1].swap(v4[1]);*/
    
        std::cout << "Just to make sure: " << v3[1][50] << " " << v2[1][85] << std::endl;
        return 0;
    }
    as the tests give rough timing of
    Option 1 11.438 s
    Option 2 11.343 s
    Option 3 11.344 s
    (using the time printed by Code::Blocks auto-run thing). So at least on this time trial, the swaps were better (albeit by 0.8%).

  10. #10
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by tabstop View Post
    Hadn't thought about member swap. Using the code:
    Code:
    int main(void) {
    
        std::vector<std::vector<int> > v1(3);
        std::vector<std::vector<int> > v2(3);
        std::vector<std::vector<int> > v3(3);
        std::vector<std::vector<int> > v4(3);
    
        for (int i = 0; i < 3; ++i) {
            for (int j = 0; j < 10000000; ++j) {
                v1[i].push_back(rand());
                v2[i].push_back(rand());
                v3[i].push_back(rand());
                v4[i].push_back(rand());
            }
        }
    
        //We'll move the middle row
        std::vector<int> aux = v4[1];
        v4[1] = v3[1];
        v3[1] = v2[1];
        v2[1] = v1[1];
        v1[1] = aux;
    
        /*std::swap(v1[1], v2[1]);
        std::swap(v1[1], v3[1]);
        std::swap(v1[1], v4[1]);*/
    
        /*v1[1].swap(v2[1]);
        v1[1].swap(v3[1]);
        v1[1].swap(v4[1]);*/
    
        std::cout << "Just to make sure: " << v3[1][50] << " " << v2[1][85] << std::endl;
        return 0;
    }
    as the tests give rough timing of
    Option 1 11.438 s
    Option 2 11.343 s
    Option 3 11.344 s
    (using the time printed by Code::Blocks auto-run thing). So at least on this time trial, the swaps were better (albeit by 0.8%).
    Then you must be timing the execution time of the whole program, including all the reallocations happening inside of push_back, and IO synchronisation inside cout. Besides, that code surely can't be what you timed because you're only using the middle vector of the three each time.

    The actual difference between the three swaps vs the five large vector copies, should be on the order of swap easily being 10000+ times faster here. A vector swap literally only swaps a few pointers around (three in practically all cases) and that's it.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  11. #11
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    If I remember correctly, Effective STL says that assign should be used for vector copying. It also discourages manually copying the vector in a for loop.

    Member functions in the STL should be used whenever possible (if they are available) as they are fine tuned for that particular container.

  12. #12
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by iMalc View Post
    Then you must be timing the execution time of the whole program, including all the reallocations happening inside of push_back, and IO synchronisation inside cout.
    Well spotted. OTOH I thought that was the point.... (how much difference does changing the mechanism of moving things around in the program as a whole)
    Quote Originally Posted by iMalc View Post
    Besides, that code surely can't be what you timed because you're only using the middle vector of the three each time.
    Well, duh. That's what the question is: "I have a 2-d vector of vectors and I want to move line X from each vector around in a cyclic sort of way." So that's what I did. (I mean I picked the value of 1 for X, but I can't see that making a huge timing difference.)

  13. #13
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    My minor confusion there due to the fact that you had presented timings to three cases and there were three vectors in each vector.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Gcc can't find obvious copy constructor
    By SevenThunders in forum C++ Programming
    Replies: 13
    Last Post: 03-19-2009, 02:41 PM
  2. calling copy constructor from template
    By Ancient Dragon in forum C++ Programming
    Replies: 3
    Last Post: 09-28-2005, 01:54 PM
  3. dynamic memory alloccation & returning objects
    By haditya in forum C++ Programming
    Replies: 8
    Last Post: 04-21-2005, 11:55 PM
  4. Copy constructors and operator=()
    By filler_bunny in forum C++ Programming
    Replies: 13
    Last Post: 08-25-2003, 07:43 AM
  5. Copy Constructor Help
    By Jubba in forum C++ Programming
    Replies: 2
    Last Post: 11-07-2001, 11:15 AM