Thread: 3D vector

  1. #1
    Registered User
    Join Date
    Dec 2007
    Posts
    385

    3D vector

    I am trying to declare a 3D vector like below. I am trying to follow the pattern of the 2D like this:
    Code:
    //2D
    vector<vector<string> > abc(500, vector<string>()); 
    
    //3D
    vector<vector<vector<string>>> abcde(500, vector<string>(), vector<string>()); 
    
    The 2D compiles but for the 3D I have a lot of compilererrors.
    I am not sure what I can be doing wrong.
    As seen I want to use push_back for 2D and 3D.
    Thanks..

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Try putting spaces between the >>> signs - some compilers get confused when they see two >> and think it's a shift operator (which of course doesn't make any sense in that location and gives lots of errors). [Note that this is in that case a bug in the compiler, really].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Chinese pâté foxman's Avatar
    Join Date
    Jul 2007
    Location
    Canada
    Posts
    404
    Plus, the constructor's arguments doesn't look right. I'll leave you fix this by yourself since I'm not sure to understand what you want to do exactly.
    I hate real numbers.

  4. #4
    Registered User
    Join Date
    Dec 2007
    Posts
    385
    Thank you.. I tried to put it like this but still get these compiler errors:
    std::vector<_Ty>::vector(unsigned int,const _Ty &,const std::allocator<_Ty> &)' : cannot convert parameter 2 from 'std::vector<_Ty>' to 'const std::vector<_Ty> &'
    Code:
    vector<vector<vector<string> > > abc(500, vector<string>(), vector<string>());
    What I want to do is to have a 3D vector.
    However I am not sure if you can have push_back on 2D and 3D or only 3D (The Last One) ?

    The vector will Ex look like: abc[1][][]

    What I want to do in the 3D vector is to push_back the 2D for example like this:
    Code:
    abc[0][string1]       //abc[0].push_back(String1); (Wonder if this is possible for a abc[0][][]
    abc[1][string2]
    abc[1][string3]
    I have done this example with a 2D vector like this: abc[0].push_back(String1);


    So 1D will not contain any data, is will only be used as a count.

    So what I do is to first push_back the 2D and when that process is finished I will loop through
    all 2D elements and take some words from here and put them to 3D.
    Last edited by Coding; 07-23-2008 at 05:48 PM.

  5. #5

    Join Date
    Apr 2008
    Location
    USA
    Posts
    76
    Quote Originally Posted by matsp View Post
    [Note that this is in that case a bug in the compiler, really].
    Really? I thought compilers' parsing mechanisms determine that it must be a right-shift operator after tokenizing, so it's an ambiguous syntax.

    But most compilers can produce an appropriate warning because if it is a right-shift operator, the entire statement is syntactically (and logically) incorrect.

    EDIT:

    Quote Originally Posted by Coding View Post
    What I want to do is to have a 3D vector.
    However I am not sure if you can have push_back on 2D and 3D or only 3D (The Last One) ?
    .

    abcde[0] is a vector<vector<string>>.
    abcde[0][0] is a vector<string>.
    So, if you wanted to push back a string on your 3D array, I'd do it like this:

    Code:
    abcde[0][0].push_back ( /* A string */ );
    
    // OR
    
    abcde[0].push_back ( /* A 1D vector of string */ );
    
    // OR
    
    abcde.push_back ( /* A 2D vector of string */ );
    Also, I believe your 3D vector constructor has the wrong number/type of arguments.
    Last edited by rudyman; 07-23-2008 at 06:33 PM.

  6. #6
    Registered User
    Join Date
    Dec 2007
    Posts
    385
    I get this to compile. What I might wonder here is if 1000 is declared for 1D or 1D, 2D and 3D.
    Code:
    vector<vector<vector<string> > > abc(1000);
    If it is only for 1D, is it possible to choose wich Dimension I want to push_back like this:
    Code:
    abc[1].push_back(String1);
    
    //When I have push_backed a few elements in 2D like above, can I do this ?
    abc[1][1].push_back(String2);
    Perheps it is tricky questions ?

  7. #7

    Join Date
    Apr 2008
    Location
    USA
    Posts
    76
    Oh, let's say you want a 3D vector that has 5 elements, you'd do it like this:
    Code:
    vector<vector<vector<string> > > abcde (5); // abcde contains 5 2D vectors
    Then, let's say you wanted to push a 2D vector of 10 elements onto abcde:
    Code:
    abcde.push_back ( vector<vector<string> > (10) ); // abcde[0] contains 10 vector<vector<string>>'s
    So abcde has 5 elements, abcde[0] has 10 elements. If you wanted abcde[0][0] to have, let's say 15 strings that say "Hello", you'd say:
    Code:
    abcde[0].push_back ( vector<string> (15, "Hello") );
    So the size doesn't apply to "inner" vectors.
    Last edited by rudyman; 07-23-2008 at 06:34 PM.

  8. #8
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    I'm pretty sure that that line gives you abc with 1000 elements, each of which being a vector<vector<string> >. So abc[0] through abc[999] are empty vectors, which you can (need to) size -- and they can all be different sizes, if you want -- and then you can deal with abc[0][0], which is a vector<string> and so can be pushed back with an actual string object.

  9. #9
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Do you know all three dimensions at the beginning? If so, just initialize the vector with all three dimensions in the constructor. It's possible, but your attempt wasn't quite right and nobody has given you the answer, only hints. See if you can figure it out.

    One way to make it easier is to use typedefs. Once you typedef the 1-D vector, then use it to create a typedef fora 2-D vector, and then use that to create the typedef for the 3-D vector. Then use the typedefs like normal objects and it will be easier to see what to do.

  10. #10
    Registered User
    Join Date
    Dec 2007
    Posts
    385
    Yes, typedefs I beleive make it more "clear".
    The first step perheps could be to declare it.

    I have tried out something like this.
    I know the size of the First Dimension (1D) wich is 1000. Second and Third Dimension I will use for
    push_back.

    I have put this code but have compileerror:
    syntax error : ')'

    Code:
    typedef std::vector<string> String1D;
    typedef std::vector<String1D> String2D;
    typedef std::vector<String2D> String3D;
    
    String3D abc(    1000,  String2D( (), String1D() )    );
    Last edited by Coding; 07-23-2008 at 06:43 PM.

  11. #11

    Join Date
    Apr 2008
    Location
    USA
    Posts
    76
    If you want to give all of the sizes at once, you can do it like this, for example:
    Code:
    String3D abc (1000, String2D(100, String1D(10)));
    But if at first all you want to give is the size of the 3D array, this is all you have to do:
    Code:
    String3D abc (1000);
    Then, you can do, e.g.:
    Code:
    abc.push_back (String2D (100));
    
    // ...
    
    abc[0].push_back (String1D (10));
    
    // ...
    abc[0][0].push_back ("A string.");
    Last edited by rudyman; 07-23-2008 at 07:03 PM.

  12. #12
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Using push_back on 3-d arrays doesn't usually make sense. Depending on your problem you might have to do extra work to ensure that each vector in a specific dimension has the correct size, since calling push_back on one dimension will change the size of only that single object in the higher dimension.

    For example, take a two dimensional grid. If you start with 1000 rows, and you want to add a column, you have to push_back the column to each of the 1000 rows. It gets even more complicated in 3-D.

  13. #13
    Registered User
    Join Date
    Dec 2007
    Posts
    385
    This made it clear for me. Nice description.
    So if I understand right you declare 2D to 100 elements and 3D to 10 elements.
    Then you push_back "A string." to abc[0][0][0]

    I did it like below but GetString doesn&#180;t get this string.
    I am not sure if I missed something. Thanks !

    Code:
    String3D abc(1000);
    
    abc.push_back (String2D (100));
    abc[0].push_back (String1D (10));
    abc[0][0].push_back ("A string.");
    
    
    std::string GetString = abc[0][0][0].c_str();

  14. #14
    Registered User
    Join Date
    Dec 2007
    Posts
    385
    >> Depending on your problem

    I will describe excatly what I am doing to get a better picture, I am a little confused myself that I am thinking right.

    For the moment I have a 2D vector that could look like this:
    (I am doing an illustration, putting the string inside [] just to illustrate more easy, I know I can&#180;t put a string like that)

    Code:
    abc[1]["1"]          //abc[1].push_back("1");
    abc[1]["1,2"]        //abc[1].push_back("1,2");
    abc[1]["1,2,3"]      //abc[1].push_back("1,2,3");
    So I have push_backed a string like this. Now I want to do something with this string. I want to put this to the 3:rd dimension like this:
    Code:
    abc[1][0]["1"]
    
    abc[1][1]["1"]
             ["2"]
    
    abc[1][2]["1"]
             ["2"]
             ["3"]
    First I have my 2D vector that I push_back and from this one I can iterate its content and put it like this to a 3D vector.

    This is why I want to be able to push_back both 2D and 3D. For with it&#180;s contents in place, I will be able to ::iterate
    from begin() to != end().
    So I will iterate the 3:rd dimension and when that is finished it will continue to iterate next 3:rd dimension for the 2:nd dimension,
    Until the 2:nd dimension also reached it&#180;s end() since every second dimension also can be different sizes because it was push_back in the 2D vector from the beginning.

    So if I can ::iterate my 2D vector and "copy" and put the contents like this to a new 3D vector, that would be great.
    This is why I want to use push_back both for the 2D and the 3D in the New 3D vector.
    Last edited by Coding; 07-23-2008 at 08:11 PM.

  15. #15

    Join Date
    Apr 2008
    Location
    USA
    Posts
    76
    Quote Originally Posted by Coding View Post
    So if I understand right you declare 2D to 100 elements and 3D to 10 elements.
    Then you push_back "A string." to abc[0][0][0]
    Yep.

    Quote Originally Posted by Coding View Post
    Code:
    abc[0][0].push_back ("A string.");
    std::string GetString = abc[0][0][0].c_str();
    Sorry, I should have said:
    Code:
    abc[0][0][0] = "A string.";
    When you use push_back, it adds the new element to the end of the vector, so the new string was at 'abc[0][0][10]' instead.

    Also, you don't need to use c_str() there, unless you want an extra cast .
    Last edited by rudyman; 07-23-2008 at 07:41 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. can some one please tell me the cause of the error ?
    By broli86 in forum C Programming
    Replies: 8
    Last Post: 06-26-2008, 08:36 PM
  2. syntax help?
    By scoobygoo in forum C++ Programming
    Replies: 1
    Last Post: 08-07-2007, 10:38 AM
  3. Certain functions
    By Lurker in forum C++ Programming
    Replies: 3
    Last Post: 12-26-2003, 01:26 AM
  4. My 3D Vector class
    By Lurker in forum C++ Programming
    Replies: 105
    Last Post: 11-16-2003, 05:58 PM
  5. Operators for 3D Vector Mathematics
    By Anarchist in forum C++ Programming
    Replies: 10
    Last Post: 01-31-2003, 07:33 PM