2015-03-19 5 views
4

Я искал более оптимальное решение для следующего, и я не могу найти его.C++ Умножающие элементы в векторе

Скажем, у меня есть вектор:

std::vector<double> vars = {1, 2, 3}

Я хочу выполнить 1 * 2 * 3 Я знаю, что я могу сделать следующее:

int multi = 1; 

for(int i = 0; (i < vars.size()-1); i++) 
{ 
    multi *= vars[i]; 
} 

Но, есть более «C + +11 "способ сделать это? Я действительно хотел сделать это, используя lambda и чтобы я мог вычислить умножение (произведение) вектора, не имея другой функции внутри класса, я бы предпочел, чтобы он вычислялся внутри функции.

+1

Ваш код вычисляет 'v [0] * v [0] * v [1] * v [2] * ... * v [ n-2] ', то есть' v [0] 'умножается дважды, а' v [n-1] 'забывается. – Walter

+0

Не знаете, каковы ваши намерения, но если вы планируете умножать все элементы вектора, вам не нужно -1 в ** vars.size() - 1 ** –

+0

Возможно, вы не ожидали результата, умножив 'int' и 'double'. – Jarod42

ответ

18

Да, как обычно, существует алгоритм (хотя это одна-х в <numeric>), std::accumulate (live example):

using std::begin; 
using std::end; 
auto multi = std::accumulate(begin(vars), end(vars), 1, std::multiplies<double>()); 

std::multiplies в <functional> тоже. По умолчанию std::accumulate использует std::plus, что добавляет два значения, заданные operator(). std::multiplies - это функтор, который вместо них умножает их.

В C++ 14 вы можете заменить std::multiplies<double> на std::multiplies<>, чей шаблон operator() и будет определять тип. Основываясь на том, что я видел с предложением Райса Эрика Ниблера, он, возможно, позже может выглядеть как vars | accumulate(1, std::multiplies<>()), но возьмите это с солью.

+0

Я знал, что есть алгоритм, я думаю, что посмотрел на него, и я уверен, что приведенный пример использовал это для вычисления умножения двух отдельных векторов. Спасибо – Phorce

+0

@Phorce, В зависимости от того, как должен выглядеть результат умножения двух векторов, также может быть полезно 'std :: transform'. Он будет генерировать последовательность продуктов каждой последовательной пары элементов. – chris

+0

Обратите внимание, что в этом ответе нет C++ 11 (кроме 'auto'). Не то, чтобы это плохо. – user2079303

3

Вы можете использовать дистанционную основанный на цикле, как:

std::vector<double> vars = {1, 2, 3} 
int multi = 1; 

for (const auto& e: vars) 
    multi *= e; 
+0

Я знаю вас от DaniWeb! (Я уверен, что вы тот же парень) спасибо за ваш ответ! – Phorce

+1

@Phorce: Да, я на Даниэве под тем же именем. Я начал здесь пару месяцев назад, потому что DaniWeb начинал устаревать. Нет проблем с помощью вашей проблемы. – NathanOliver

Смежные вопросы