Если вы пытаетесь добавить один вектор
к другому, вы можете использовать что-то вроде следующего. Это из одной из моих библиотек утилит - две перегрузки operator + =
для std :: vector
: одна добавляет один элемент к вектору
, другая - весь вектор
:
template <typename T>
std::vector<T>& operator+=(std::vector<T>& a, const std::vector<T>& b)
{
a.insert(a.end(), b.begin(), b.end());
return a;
}
template <typename T>
std::vector<T>& operator+=(std::vector<T>& aVector, const T& aObject)
{
aVector.push_back(aObject);
return aVector;
}
Если вы пытаетесь выполнить суммирование (то есть создать новый вектор
, содержащий суммы элементов двух других вектора
] s) можно использовать что-то вроде следующего:
#include <algorithm>
#include <functional>
template <typename T>
std::vector<T> operator+(const std::vector<T>& a, const std::vector<T>& b)
{
assert(a.size() == b.size());
std::vector<T> result;
result.reserve(a.size());
std::transform(a.begin(), a.end(), b.begin(),
std::back_inserter(result), std::plus<T>());
return result;
}
Аналогичным образом можно реализовать перегрузку operator + =
.
Если в вашем коде есть ошибки, то это проблема правильности, а не эффективности.
Чтобы достичь «u [i] = u [i] + v [i] для всех i», я бы сделал в основном то, что вы сделали:
assert(u.size() == v.size()); // will fail with your initialization code, since
// your "result" has size 0, not size 10.
// perhaps do u.resize(v.size());
for (size_t i = 0; i < u.size(); ++i) {
u[i] += v[i];
}
Если вы действительно заботитесь о производительности вашего Программа (то есть, вы написали базовую версию, и она настолько медленная, что ваша программа не выполняет какое-то требование, и вы доказали, что это код, который занимает большую часть времени), тогда вы можете попробовать:
Тем не менее, вы не должны беспокоиться о производительности до того, как ваш код верен ;-). «Сделайте так, чтобы это работало, сделайте это правильно, сделайте это быстро» - это разумный девиз, хотя часто вам не нужно идти до шага 3.
std::valarray
на самом деле имеет именно то operator+=
, которое вы хотите. Прежде чем заменять все свои векторы на значения, имейте в виду, что это не обязательно означает, что он «более эффективен», чем простой цикл - я не знаю, насколько серьезно разработчики воспринимают это valarray
. Вы всегда можете посмотреть на источник в вашей реализации. Я также не знаю, почему арифметическая функция нескольких данных в valarray
не была определена как часть vector
, но обычно есть причина.
Код кажется нормальным, но мое первое желание было бы изменить любой код, заполняющий вектор значениями, чтобы добавить к значениям в первом векторе ссылку на первый вектор и добавить к ней непосредственно, а не создавать новый вектор, который возвращается. Это просто неэффективно.
Если вы не можете изменить функцию таким образом, возможно, вы можете изменить ее так, чтобы она брала ссылку на вектор, который она очищает, а затем вставляет значения, чтобы вы не копировали векторы вокруг. Это может дорого обойтись, если вы много делаете.
Еще один придирчивый, если вы пытаетесь получить это как можно быстрее, вы должны использовать преинкремент с итераторами, а не постинкремент. Временное, которое создает постинкремент, не может быть оптимизировано при работе с перегруженными операторами, а не со встроенными типами. Таким образом, вы продолжаете создавать и уничтожать временную каждую итерацию вашего цикла. РЕДАКТИРОВАТЬ: Как было отмечено в комментариях, вы используете индексы здесь, а не итераторы (я, очевидно, не уделял достаточного внимания), так что этот совет не применим здесь. Тем не менее, в тех случаях, когда вы используете итераторы, это все еще действует.
Кроме этого, если вы пытаетесь добавить все элементы двух векторов вместе, то, вероятно, у вас есть примерно такое же эффективное решение, которое вы получите. Есть лучшие способы, если вы беспокоитесь о вставке элементов одного вектора в другой, но если вы просто складываете их значения вместе, то у вас хорошо получается. Я ожидаю, что использование любых алгоритмов STL будет в лучшем случае столь же быстрым и, вероятно, медленным из-за дополнительных вызовов функций, но вам, вероятно, придется профилировать его, чтобы быть уверенным.
Вам нужно сначала инициализировать result
всеми нулями; простое объявление переменной фактически не выделяет никаких элементов.
Попробуйте следующее:
vector<double> result(10); // default-initialize to 10 elements
vector<double> result_temp;
for(int i=0; i< 10; i++)
result_temp.push_back(i);
for(int i =0; i< result_temp.size();i++)
result[i] += result_temp[i];
Я с @James McNellis - этот код кажется правильным, если result
и result_temp
имеют одинаковую длину.
Также - почему вы объявили результат
, но использовали переменную result_v
- так ли на самом деле написан код? Если да, то это проблема
Похоже, что проблема заключается в обращении к несуществующим значениям result
. tzaman показывает, как инициализировать result 10 элементами, каждый из которых имеет значение 0.
Теперь нужно вызвать функцию transform
(из plus
(из
std::transform(result.begin(), result.end(), result_temp.begin(),
result.begin(), std::plus<double>());
Это итерирует result
и result_temp
, применяет plus
, который складывает удвоенные значения, и записывает сумму обратно в result
.