A proper way to create a matrix in c++

后端 未结 10 2310
無奈伤痛
無奈伤痛 2020-11-27 05:33

I want to create an adjacency matrix for a graph. Since I read it is not safe to use arrays of the form matrix[x][y] because they don\'t check for range, I deci

相关标签:
10条回答
  • 2020-11-27 06:33

    The standard vector does NOT do range checking by default.

    i.e. The operator[] does not do a range check.

    The method at() is similar to [] but does do a range check.
    It will throw an exception on out of range.

    std::vector::at()
    std::vector::operator[]()

    Other notes: Why a vector<Pointers> ?
    You can quite easily have a vector<Object>. Now there is no need to worry about memory management (i.e. leaks).

    std::vector<std::vector<bool> >   m;
    

    Note: vector<bool> is overloaded and not very efficient (i.e. this structure was optimized for size not speed) (It is something that is now recognized as probably a mistake by the standards committee).

    If you know the size of the matrix at compile time you could use std::bitset?

    std::vector<std::bitset<5> >    m;
    

    or if it is runtime defined use boost::dynamic_bitset

    std::vector<boost::dynamic_bitset>  m;
    

    All of the above will allow you to do:

    m[6][3] = true;
    
    0 讨论(0)
  • 2020-11-27 06:34

    In addition to all the answers that have been posted so far, you might do well to check out the C++ FAQ Lite. Questions 13.10 - 13.12 and 16.16 - 16.19 cover several topics related to rolling your own matrix class. You'll see a couple of different ways to store the data and suggestions on how to best write the subscript operators.

    Also, if your graph is sufficiently sparse, you may not need a matrix at all. You could use std::multimap to map each vertex to those it connects.

    0 讨论(0)
  • 2020-11-27 06:36

    Mind you std::vector doesn't do range checking either.

    0 讨论(0)
  • 2020-11-27 06:37

    Note that also you can use boost.ublas for matrix creation and manipulation and also boost.graph to represent and manipulate graphs in a number of ways, as well as using algorithms on them, etc.

    Edit: Anyway, doing a range-check version of a vector for your purposes is not a hard thing:

    template <typename T>
    class BoundsMatrix
    {
            std::vector<T> inner_;
            unsigned int dimx_, dimy_;
    
    public:
            BoundsMatrix (unsigned int dimx, unsigned int dimy)
                    : dimx_ (dimx), dimy_ (dimy)
            {
                    inner_.resize (dimx_*dimy_);
            }
    
            T& operator()(unsigned int x, unsigned int y)
            {
                    if (x >= dimx_ || y>= dimy_)
                            throw std::out_of_range("matrix indices out of range"); // ouch
                    return inner_[dimx_*y + x];
            }
    };
    

    Note that you would also need to add the const version of the operators, and/or iterators, and the strange use of exceptions, but you get the idea.

    0 讨论(0)
提交回复
热议问题