Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
B.Eckel - Thinking in C++, Vol.2, 2nd edition.pdf
Скачиваний:
50
Добавлен:
08.05.2013
Размер:
2.09 Mб
Скачать

int main() { vector<Inventory> vi;

generate_n(back_inserter(vi), 15, InvenGen()); print(vi, "vi");

vector<float> disc; generate_n(back_inserter(disc), 15, DiscGen()); print(disc, "Discounts:");

vector<Inventory> discounted; transform(vi.begin(),vi.end(), disc.begin(),

back_inserter(discounted), Discounter()); print(discounted, "discounted");

} ///:~

Discounter is a function object that, given an Inventory object and a discount percentage, produces a new Inventory with the discounted price. DiscGen just generates random discount values between 1 and 10 percent to use for testing. In main( ), two vectors are created, one for Inventory and one for discounts. These are passed to transform( ) along with a

Discounter object, and transform( ) fills a new vector<Inventory> called discounted.

Numeric algorithms

These algorithms are all tucked into the header <numeric>, since they are primarily useful for performing numerical calculations.

<numeric>

T accumulate(InputIterator first, InputIterator last, T result); T accumulate(InputIterator first, InputIterator last, T result,

BinaryFunction f);

The first form is a generalized summation; for each element pointed to by an iterator i in [first, last), it performs the operation result = result + *i, where result is of type T. However, the second form is more general; it applies the function f(result, *i) on each element *i in the range from beginning to end. The value result is initialized in both cases by resultI, and if the range is empty then resultI is returned.

Note the similarity between the second form of transform( ) and the second form of accumulate( ).

<numeric>

T inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init);

Tinner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init

BinaryFunction1 op1, BinaryFunction2 op2);

Chapter 15: Multiple Inheritance

331

Calculates a generalized inner product of the two ranges [first1, last1) and [first2, first2 + (last1 - first1)). The return value is produced by multiplying the element from the first sequence by the “parallel” element in the second sequence, and then adding it to the sum. So if you have two sequences {1, 1, 2, 2} and {1, 2, 3, 4} the inner product becomes:

(1*1) + (1*2) + (2*3) + (2*4)

Which is 17. The init argument is the initial value for the inner product; this is probably zero but may be anything and is especially important for an empty first sequence, because then it becomes the default return value. The second sequence must have at least as many elements as the first.

While the first form is very specifically mathematical, the second form is simply a multiple application of functions and could conceivably be used in many other situations. The op1 function is used in place of addition, and op2 is used instead of multiplication. Thus, if you applied the second version of inner_product( ) to the above sequence, the result would be the following operations:

init = op1(init, op2(1,1)); init = op1(init, op2(1,2)); init = op1(init, op2(2,3)); init = op1(init, op2(2,4));

Thus it’s similar to transform( ) but two operations are performed instead of one.

<numeric>

OutputIterator partial_sum(InputIterator first, InputIterator last, OutputIterator result);

OutputIterator partial_sum(InputIterator first, InputIterator last, OutputIterator result, BinaryFunction op);

Calculates a generalized partial sum. This means that a new sequence is created, beginning at result, where each element is the sum of all the elements up to the currently selected element in [first, last). For example, if the original sequence is {1, 1, 2, 2, 3} then the generated sequence is {1, 1 + 1, 1 + 1 + 2, 1 + 1 + 1 + 2 + 2, 1 + 1 + 1 + 2 + 2 + 3}, that is, {1, 2, 4, 6, 9}.

In the second version, the binary function op is used instead of the + operator to take all the “summation” up to that point and combine it with the new value. For example, if you use multiplies<int>( ) as the object for the above sequence, the output is {1, 1, 2, 4, 12}. Note that the first output value is always the same as the first input value.

The return value is the end of the output range [result, result + (last - first) ).

<numeric>

OutputIterator adjacent_difference(InputIterator first, InputIterator last, OutputIterator result);

OutputIterator adjacent_difference(InputIterator first, InputIterator last, OutputIterator result, BinaryFunction op);

Chapter 15: Multiple Inheritance

332

Calculates the differences of adjacent elements throughout the range [first, last). This means that in the new sequence, the value is the value of the difference of the current element and the previous element in the original sequence (the first value is the same). For example, if the original sequence is {1, 1, 2, 2, 3}, the resulting sequence is {1, 1 – 1, 2 – 1, 2 – 2, 3 – 2}, that is: {1, 0, 1, 0, 1}.

The second form uses the binary function op instead of the operator to perform the “differencing.” For example, if you use multiplies<int>( ) as the function object for the above sequence, the output is {1, 1, 2, 4, 6}.

The return value is the end of the output range [result, result + (last - first) ).

Example

This program tests all the algorithms in <numeric> in both forms, on integer arrays. You’ll notice that in the test of the form where you supply the function or functions, the function objects used are the ones that produce the same result as form one so the results produced will be exactly the same. This should also demonstrate a bit more clearly the operations that are going on, and how to substitute your own operations.

//: C05:NumericTest.cpp #include "PrintSequence.h" #include <numeric> #include <algorithm> #include <iostream> #include <iterator> #include <functional> using namespace std;

int main() {

int a[] = { 1, 1, 2, 2, 3, 5, 7, 9, 11, 13 }; const int asz = sizeof a / sizeof a[0]; print(a, a + asz, "a", " ");

int r = accumulate(a, a + asz, 0); cout << "accumulate 1: " << r << endl; // Should produce the same result:

r = accumulate(a, a + asz, 0, plus<int>()); cout << "accumulate 2: " << r << endl;

int b[] = { 1, 2, 3, 4, 1, 2, 3, 4, 1, 2 }; print(b, b + sizeof b / sizeof b[0], "b", " "); r = inner_product(a, a + asz, b, 0);

cout << "inner_product 1: " << r << endl; // Should produce the same result:

r= inner_product(a, a + asz, b, 0, plus<int>(), multiplies<int>());

Chapter 15: Multiple Inheritance

333

Соседние файлы в предмете Численные методы
  • #
    08.05.20133.99 Mб22A.Menezes, P.van Oorschot,S.Vanstone - HANDBOOK OF APPLIED CRYPTOGRAPHY.djvu
  • #
  • #
    08.05.20135.91 Mб24B.Eckel - Thinking in Java, 3rd edition (beta).pdf
  • #
  • #
    08.05.20136.09 Mб17D.MacKay - Information Theory, Inference, and Learning Algorithms.djvu
  • #
    08.05.20133.85 Mб15DIGITAL Visual Fortran ver.5.0 - Programmers Guide to Fortran.djvu
  • #
    08.05.20131.84 Mб12E.A.Lee, P.Varaiya - Structure and Interpretation of Signals and Systems.djvu