Pages

Friday, February 19, 2010

STL. Vector. Hello, World program

Here is a simple Hello. World! program for the STL vector:
#include <cstring>
#include <vector>
#include <iostream>
using namespace std;

const char* str = "Hello, World!";

int main()
{
vector<char> v(str, str + strlen(str));
for (unsigned int i = 0; i < v.size(); i++)
{
cout << v[i];
}
cout << endl;
return 0;
}

The firstl line in the main function:
vector<char> v(str, str + strlen(str));

converted the string (array of char) into the vector. This vector constructor can be persented as:
template <typename InputIterator>
vector(InputIterator first, InputIterator last)

vector is a sequence container - it is a collection of objects, all of the same type, into a strictly linear arrangement. vector provides random access to this sequence. The most time consuming operations with the vector are inserting and deleting at the end. The time of these operations is constant for the vector.

We are talking about the STL - Standard Template Library, so it makes sense to modify the program code listed above:
#include <cstring>
#include <vector>
#include <iostream>
using namespace std;

const char* str = "Hello, World!";

template<typename Container>
void print(Container container)
{
for (unsigned int i = 0; i < container.size(); i++)
{
cout << container[i];
}
cout << endl;
}

int main()
{
vector<char> v(str, str + strlen(str));
print(v);
return 0;
}

Template function print was added to the program. This function will allow to print out an STL container. Method size() used in this function gives the number of elements in the container.

In the following form this function looks more atractive:
template<typename Container>
void print(Container container)
{
Container::iterator it;
for (it = container.begin(); it < container.end(); it++)
{
cout << *it;
}
cout << endl;
}
Now it works with the iterators - functions begin() and end() returns iterators declared as Container::iterator which can be derefferenced and used, for example, for the printing of the container elements.

Two other linear containers are deque and list.
In our program we can replace vector with deque:
#include <cstring>
#include <deque>
#include <iostream>
using namespace std;

const char* str = "Hello, World!";

template<typename Container>
void print(Container container)
{
Container::iterator it;
for (it = container.begin(); it < container.end(); it++)
{
cout << *it;
}
cout << endl;
}

int main()
{
deque<char> v(str, str + strlen(str));
print(v);
return 0;
}

Our function print works with this container too. All methods (begin(), end(), size()) used in this program are the same for the vector and deque (the list does not allow ++ operator).

In the same way the STL algoritms use the containers - these algorithms are the template functions (same as our print function). For example:
#include <cstring>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

const char* str = "Hello, World!";

template<typename Container>
void print(Container container)
{
Container::iterator it;
for (it = container.begin(); it < container.end(); it++)
{
cout << *it;
}
cout << endl;
}

int main()
{
vector<char> v(str, str + strlen(str));
print(v);
vector<char>::iterator where = find(v.begin(), v.end(), 'W');
if (where != v.end())
{
vector<char> found(where, v.end());
print(found);
}
return 0;
}
This program found character 'W' in the input container, made new container from the found position and printed it out:
Or here is the reverse algorithm:
#include <cstring>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

const char* str = "Hello, World!";

template<typename Container>
void print(Container container)
{
Container::iterator it;
for (it = container.begin(); it < container.end(); it++)
{
cout << *it;
}
cout << endl;
}

int main()
{
vector<char> v(str, str + strlen(str));
print(v);
reverse(v.begin(), v.end());
print(v);
return 0;
}
One more sample using vector:
#include <iostream>
#include <vector>
#include <numeric>
using namespace std;

int main()
{
int x[5] = { 2, 3, 5, 7, 11 };
vector<int> v(x, x + 5);
int sum = accumulate(v.begin(), v.end(), 0);
cout << "sum = " << sum << endl;
return 0;
}
This small program above calculates the sum of 5 integers (the result is 28). Algorithm accumulate (from numeric header file) is used in this code. Integer numbers can be replaced by double:
#include <iostream>
#include <vector>
#include <numeric>
using namespace std;

int main()
{
double x[5] = { 0.2, 0.3, 0.5, 0.7, 1.1 };
vector<double> v(x, x + 5);
double sum = accumulate(v.begin(), v.end(), 0.0);
cout << "sum = " << sum << endl;
return 0;
}
The result is 2.8. This accumulate function is also a template function that works with the iterators and may look like:
template <typename InputIterator, typename T>
T accumulate(InputIterator first, InputIterator last, T init)
{
while (first != last)
{
init = init + *first;
++first;
}
return init;
}
Here are a few articles about the basic STL:
1. A Practical Guide to STL

2. An Introduction to the Standard Template Library (STL)
3. C++ Vectors

No comments:

Post a Comment