Надлежащий способ создать матрицу в C++

Второй (необязательный) аргумент FTP.retrlines - callback.

FTP.retrlines(command[, callback])

Вы можете использовать его как:

lines = []
sess.retrlines('NLST ' + path, lines.append)

См. также Создание списка из ретрансляции в Python .

27
задан duffymo 6 March 2009 в 12:31
поделиться

8 ответов

Стандартный вектор НЕ делает проверки диапазона по умолчанию.

т.е. оператор [] не делает проверки принадлежности к диапазону.

метод в () похож [], но действительно делает проверку принадлежности к диапазону.
Это выдаст исключение на из диапазона.

станд.:: вектор:: в ()
станд.:: вектор:: оператор [] ()

Другие примечания: Почему vector< Pointers>?
у Вас может довольно легко быть vector< Object>. теперь нет никакой потребности волноваться об управлении памятью (т.е. утечки).

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

Примечание: vector< bool> перегружается и не очень эффективный (т.е. эта структура была оптимизирована для размера не скорость) (Это - что-то, что теперь распознано как, вероятно, ошибка комитетом по стандартам).

, Если Вы знаете размер матрицы во время компиляции, Вы могли бы использовать станд.:: bitset?

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

или если это - время выполнения, определил повышение использования:: dynamic_bitset

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

Все вышеупомянутое позволит Вам делать:

m[6][3] = true;
10
ответ дан Martin 14 October 2019 в 13:45
поделиться

Лучший способ:

Делают Ваш собственный матричный класс, тот способ, которым Вы управляете каждым последним аспектом его, включая проверку диапазона.

, например, Если Вам нравится" [x] [y]" нотация, сделайте это:

class my_matrix {
  std::vector<std::vector<bool> >m;
public:
  my_matrix(unsigned int x, unsigned int y) {
    m.resize(x, std::vector<bool>(y,false));
  }
  class matrix_row {
    std::vector<bool>& row;
  public:
    matrix_row(std::vector<bool>& r) : row(r) {
    }
    bool& operator[](unsigned int y) {
      return row.at(y);
    }
  };
  matrix_row& operator[](unsigned int x) {
    return matrix_row(m.at(x));
  }
};
// Example usage
my_matrix mm(100,100);
mm[10][10] = true;

нбар. Если Вы программируете как это тогда, C++ так же безопасен как все те другие "безопасные" языки.

8
ответ дан Jimmy J 14 October 2019 в 13:45
поделиться

Обратите внимание, что также можно использовать boost.ublas для матричного создания и управления и также boost.graph, чтобы представить и управлять графиками различными способами, а также алгоритмами использования на них, и т.д.

Редактирование : Так или иначе выполнение версии проверки принадлежности к диапазону вектора в Ваших целях не является твердой вещью:

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

Примечание, что необходимо было бы также добавить версию константы операторов, и/или итераторы и странное использование исключений, но Вы получаете идею.

18
ответ дан Diego Sevilla 14 October 2019 в 13:45
поделиться

То, что я сделал бы, создают мой собственный класс для контакта с матрицами (вероятно, как массив [x*y], потому что я больше привык к C (и у меня была бы своя собственная проверка границ), но Вы могли использовать векторы или любую другую подструктуру в том классе).

Добираются, Ваш материал, функциональный первый тогда, волнуются о том, как быстро он работает. При разработке класса правильно можно вытащить массив [x*y] реализация и заменить его векторами или битовыми масками или независимо от того, что Вы хотите, не изменяя остальную часть кода.

я не полностью уверен, но я вещь, это - то, что классы были предназначены для, способность абстрагировать реализацию хорошо с глаз долой и обеспечить только интерфейсу:-)

3
ответ дан paxdiablo 14 October 2019 в 13:45
поделиться

Также подумайте, насколько велик ваш график / матрица, имеет ли значение производительность? Является ли график статичным или может расти со временем, например, добавив новые ребра?

1
ответ дан siddhadev 14 October 2019 в 13:45
поделиться

В дополнение ко всем ответам, которые были отправлены до сих пор, Вы могли бы преуспеть для проверки FAQ C++, Облегченный . Вопросы 13.10 - 13.12 и 16.16 - 16.19 затрагивают несколько тем, связанных с прокруткой Вашего собственного матричного класса. Вы будете видеть несколько различных способов хранить данные и предложения о том, как лучше всего записать нижние операторы.

кроме того, если Ваш график достаточно редок, Вам, возможно, не понадобится матрица вообще. Вы могли использовать std::multimap для отображения каждой вершины на тех, которых она соединяет.

3
ответ дан Michael Kristofik 14 October 2019 в 13:45
поделиться

Обратите внимание std::vector не делает проверки диапазона также.

1
ответ дан Alexis Wilke 14 October 2019 в 13:45
поделиться

Если вы хотите производительность массива 'C', но с дополнительной безопасностью и STL-подобной семантикой (итераторы, begin() и end() и т. Д.), Используйте boost::array .

По сути это шаблонная оболочка для 'C'-массивов с некоторыми NDEBUG -подключаемыми утверждениями проверки диапазона (а также с некоторыми std::range_error исключающими объектами).

Я использую такие вещи, как

boost::array<boost::array<float,4>,4> m;

вместо

float m[4][4];

все время, и это прекрасно работает (с соответствующими typedefs, чтобы в любом случае подавить многословие).


ОБНОВЛЕНИЕ: После некоторого обсуждения в комментариях здесь относительной производительности boost::array против boost::multi_array, я бы отметил, что этот код, скомпилированный с g++ -O3 -DNDEBUG на Debian / Lenny amd64 на Q9450 с 1333 МГц DDR3 RAM занимает 3,3 с для boost::multi_array против 0,6 с для boost::array.

#include <iostream>
#include <time.h>
#include "boost/array.hpp"
#include "boost/multi_array.hpp"

using namespace boost;

enum {N=1024};

typedef multi_array<char,3> M;
typedef array<array<array<char,N>,N>,N> C;

// Forward declare to avoid being optimised away
static void clear(M& m);
static void clear(C& c);

int main(int,char**)
{
  const clock_t t0=clock();

  {
    M m(extents[N][N][N]);
    clear(m);
  }

  const clock_t t1=clock();

  {
    std::auto_ptr<C> c(new C);
    clear(*c);
  }

  const clock_t t2=clock();

  std::cout 
    << "multi_array: " << (t1-t0)/static_cast<float>(CLOCKS_PER_SEC) << "s\n"
    << "array      : " << (t2-t1)/static_cast<float>(CLOCKS_PER_SEC) << "s\n";

  return 0;
}

void clear(M& m)
{
  for (M::index i=0;i<N;i++)
    for (M::index j=0;j<N;j++)
      for (M::index k=0;k<N;k++)
    m[i][j][k]=1;
}


void clear(C& c)
{
  for (int i=0;i<N;i++)
    for (int j=0;j<N;j++)
      for (int k=0;k<N;k++)
    c[i][j][k]=1;
}
5
ответ дан timday 14 October 2019 в 13:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: