|
 |
 |
[an error occurred while processing this directive]
- 2. Change arrays to vectors
In order to provide more flexibility, replace the array in your implementation with the STL vector. The vector container is an expandable sequential container that is analogous to the C++ array. The main difference is that you dont have to specify the upper limit for the vector. It expands itself as the new element is being added.
// fe3.cpp
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
using namespace std;
void PrintM(double valueF)
{
const double factor = 0.09290304;
cout << setprecision(2) << setiosflags(ios::fixed) <<
factor*valueF << endl;
}
int main()
{
vector <double> areaF;
areaF.push_back(1200.0);
areaF.push_back(1080.78);
areaF.push_back(981.5);
areaF.push_back(224.70);
for_each (areaF.begin(), areaF.end(), PrintM);
return 0;
}
In order to use vectors in this program, you must include the <vector> header file. Also, the vector initialization was changed. The vector is initialized using the push_back function.
Because you havent changed the data type of the data, dont make changes in the PrintM function. Therefore, the for_each function remained the same too.
- 3. Trying to change the class with the nonmutating algorithm
As noted before, the data should not be changed with a nonmutating algorithm. This is specified in the STL standard. However, not all compilers check that the function used in the for_each algorithm does not change the data. If you try to replace the PrintM function with the following one
void PrintM(double &valueF)
{
const double factor = 0.09290304;
valueF = factor*valueF;
cout << setprecision(2) << setiosflags(ios::fixed) <<
valueF << endl;
}
you wont get any warnings if you run Microsoft Visual C++ 5. The code will be compiled and the main function
// fe1.cpp
#include <iostream>
#include <iomanip>
#include <algorithm>
using namespace std;
int main()
{
double areaF[]= {1200.0, 1080.78, 981.5, 224.70};
for_each (areaF, areaF + 4, PrintM);
for (int i= 0; i < 4; i++) cout << areaF[i] << endl;
return 0;
}
will produce the output
111.48
100.41
91.18
20.88
111.48
100.41
91.18
20.88
that confirms the changes.
Comments
STL provides a general algorithm that replaces the for loop for the containers. The for_each algorithm applies a specified function to a range of a container. Even if the range is specified with the iterators that point to the beginning and to the end of it, and if you dont know the number of elements in the range, the for_each algorithm can handle such an approach.
The for_each algorithm has a linear complexity, which means it executes the function a number of times proportional to the length of the range.
9.4 Compare two sequences?
Problem
One common problem I have to solve while working with the STL containers is comparing two ranges of sequences. What algorithms should I use to compare the ranges? What is the difference between the equal and the mismatch algorithms?
Technique
The equal and mismatch algorithms carry out the same task. They compare the ranges of sequences and find whether the ranges differ. The behavior of the two algorithms is very similar. The difference between them is that equal simply returns false if the two ranges differ. The mismatch algorithm returns the first location where they differ.
This How-To discusses how the two algorithms are properly used.
Steps
- 1. Using the equal algorithm
Consider an example of data sets of integers for an interactive computer game. You want to maintain the integers in the vector and consider the vector a pattern for matching with other data structures. For example, you want to know if the incoming data differs from the pattern that you maintain.
In the program, keep the pattern in the pattern vector. Read the incoming data in the inData vector, and compare the data with pattern. You must make a few assumptions. First, in order to make the program simpler, dont read the data. Instead, hardcode the inData initialization. Second, assume that you already know that the proper range that could match the incoming data starts with the pattern[1] element. You also know that the length of inData will not exceed the length of the rest of pattern.
// equal_a.cpp
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
vector <int> pattern;
vector <int> inData;
vector <int>::iterator i;
pattern.push_back(12);
pattern.push_back(25);
pattern.push_back(33);
pattern.push_back(49);
inData.push_back(25);
inData.push_back(33);
inData.push_back(48);
i = pattern.begin();
i++;
if (equal(i, pattern.end(), inData.begin()))
cout << The ranges are equal << endl;
else
cout << The ranges are not equal << endl;
return 0;
}
The most interesting lines in this very short program are
i = pattern.begin();
i++;
if (equal(i, pattern.end(), inData.begin()))
The first line creates an iterator that helps to walk through the pattern vector. The second line increments the iterator. (In a bigger program, you would write some code that finds the beginning of the range in the pattern that would be checked against InData.) The third line uses the equal algorithm with three arguments. The first argument points to the beginning of the pattern. It should start with the second element of the pattern vector, where the i iterator points now. The second argument points after the end of the range, and the end() member function of the vector container is used for this purpose. The third argument points to the beginning of the second range, which is compared with the first one. You will use the begin() function of the vector container.
The output will show
The ranges are not equal
|