2010-10-05 6 views
4

Я пишу класс, содержащий матрицу (двойных значений), представленную как vector<vector<double>>;vector resize() automatic fill

Я хочу реализовать operator=, чтобы заполнить мою матрицу деталями данной разреженной матрицы. Я пишу следующий код:

RegMatrix& RegMatrix::operator=(const SparseMatrix rhs){ 
    if(*this != rhs){ 
     _matrix.clear(); 
     _matrix.resize(rhs.getRow()); 
     int i; 
     for(i=0;i<rhs.getRow();++i){ 
      _matrix.at(i).resize(rhs.getCol()); 
     } 

     for(i=0;i<rhs.getSize();++i){ 
      Element e = rhs.getElement(i); 
      _matrix[e._row][e._col] = e._val; 
     } 
    } 

    return *this; 
} 

заполнения ли метод resize() автоматически вектор с нулями? Является ли моя реализация одобренной?

ответ

5

Новые элементы принимают значение по умолчанию vector или определенное значение, если вы используете перегрузку resize с двумя параметрами.

void resize(
    size_type _Newsize, 
    Type _Val 
); 

В вашем случае, по умолчанию будет пустой vector<double> - если это не то, что вы хотите, передать то, что вы хотите поставить там перегрузки выше.

Существующие элементы не изменяются.

+0

так, если я хочу двумерный вектор zise RowXCol и элемент каждого внутреннего вектора будет иметь значение 0, я должен изменить линию так, что это будет выглядеть например: _matrix.at (i) .resize (rhs.getCol(), 0); ? – limlim

+0

@limlim: Вам не нужно его менять. Вы уже пропустили этот нуль * неявно *. Вы также можете передать этот ноль явно, но ничего не измените.Если вы считаете, что передача этого 0 явно делает ваш код более четким, тогда вы можете пойти туда и поместить его туда. Но это не будет иметь разницы в функциональности. – AnT

+0

Если я не ошибаюсь, изменение размера не приведет к нулю существующих элементов. Если это то, что вы хотите сделать, используйте назначение (проверьте мой ответ для большего). – JoshD

0

Ни один из методов std::vector<> никогда не использовал любую форму инициализации по умолчанию. std::vector<> требуется только его элементы CopyConstructible и Назначаемый, но не требует от них По умолчаниюConstructible. Каждый раз, когда вы сталкиваетесь с ситуацией, когда некоторые элементы кажутся построенными «из ничего» (как в случае с вашими вызовами resize), это обычно означает, что используемый вами методимеет дополнительный параметр, который позволяет вам передавать значение, из которого будут построены новые элементы. Мы не часто замечаем, что, поскольку эти аргументы всегда снабжаются значениями по умолчанию, равными () -инициализированным элементом соответствующего типа.

В вашем случае

_matrix.at(i).resize(rhs.getCol()); 

фактически переведены на

_matrix.at(i).resize(rhs.getCol(), double()); 

вызова, а это означает, что формально это ты, кто неявно передавая начальное значение для новых элементов.

double() оценивает на нуль, поэтому да, векторы столбцов будут заполнены нулями изначально.

+0

Нет, только новые элементы (если они есть) будут равны нулю. –

+0

@ c-urchin: А? Во-первых, когда я говорю «новые элементы» средние вновь добавленные элементы, которые достаточно ясны. Во-вторых, мое последнее замечание относится к конкретному коду OP, где вектор сначала * пуст *. Таким образом, он будет * заполнен * нулями после изменения размера, как я уже сказал. – AnT

+0

Почему так обидно? Фактически, OP говорит (пожалуйста, перечитайте его) «повторно заполнить», что означает, что некоторые значения уже установлены. –

2

Если вы хотите обнулить весь 2d массив, вы можете использовать assign function of vector:

v.assign(size, vector<double>(size, 0.)); 

Это сделает 2d вектор sizeXsize заполненный нулями.

В вашем случае:

RegMatrix& RegMatrix::operator=(const SparseMatrix rhs){ 
    if(*this != rhs){ 
     _matrix.assign(rhs.getRow(), vector<double>(rhs.getCol(), 0.)); 

     for(i=0;i<rhs.getSize();++i){ 
      Element e = rhs.getElement(i); 
      _matrix[e._row][e._col] = e._val; 
     } 
    } 

    return *this; 
} 
+0

Никакой официальной необходимости в явном '0'. 'v.assign (размер, вектор (размер))' будет делать то же самое. – AnT