Go back to Richel Bilderbeek's homepage.

Go back to Richel Bilderbeek's C++ page.

 

 

 

 

 

(C++) Exercise #9: No for-loops

 

Difficulty: 5/10

Date added: 29th of December 2009

 

In this exercise, you learn to replace for-loops by algorithms.

 

Reading the literature, one reads:

 

Prefer algorithms over loops [1][2]

 

This is easier said than done.

 

In this exercise you must replace for-loops by using a combination of all those algorithm things like std::for_each, std::transform, std::bind1st, std::bind2nd, std::multiplies and more of the likes. It is up to you to find the correct combination.

 

The exercises are unordered. Some require Boost, but will be in namespace std after the C++0x standard.

 

 

 

 

 

Table of contents

 

 

 

 

 

 

Question #0: Triple

 

Replace the for-loop. You will need:

 

#include <vector>
 
void Triple(std::vector<int>& v)
{
  const int sz = v.size();
  for (int i=0; i!=sz; ++i)
  {
    v[i]*=3;
  }
}

 

 

 

 

 

 

Question #1: AddTwo

 

Replace the for-loop. You will need:

 

#include <vector>
 
const std::vector<int> AddTwo(const std::vector<int>& v)
{
  std::vector<int> v_new(v); //Copy original vector
  const int sz = v.size();
  for (int i=0; i!=sz; ++i)
  {
    v_new[i]+=2;
  }
  return v_new;
}

 

 

 

 

 

 

Question #2: Multiply

 

Replace the for-loop. You will need:

 

#include <vector>
 
void Multiply(std::vector<int>& v, const int x)
{
  const int sz = v.size();
  for (int i=0; i!=sz; ++i)
  {
    v[i]*=x;
  }
}

 

 

 

 

 

 

Question #3: Add

 

Replace the for-loop. You will need:

 

#include <vector>
 
const std::vector<int> Add(const std::vector<int>& v, const int x)
{
  std::vector<int> v_new(v); //Copy original vector
  const int sz = v.size();
  for (int i=0; i!=sz; ++i)
  {
    v_new[i]+=x;
  }
  return v_new;
}

 

 

 

 

 

 

Question #4: Widget::DoIt on Widget

 

Replace the for-loop. You will need:

 

#include <vector>
 
struct Widget
{
  void DoIt() const { /* do it */ }
};
 
void DoIt(const std::vector<Widget>& v)
{
  const int sz = v.size();
  for (int i=0; i!=sz; ++i)
  {
    v[i].DoIt();
  }
}

 

 

 

 

 

 

Question #5: Widget::DoItOften on Widget

 

Replace the for-loop. You will need:

 

#include <vector>
 
struct Widget
{
  void DoItOften(const int n) const { /* do it n times */ }
};
 
void DoItOften(const std::vector<Widget>& v, const int n)
{
  const int sz = v.size();
  for (int i=0; i!=sz; ++i)
  {
    v[i].DoItOften(n);
  }
}

 

 

 

 

 

 

Question #6: Widget::DoIt on Widget*

 

Replace the for-loop. You will need:

 

#include <vector>
 
struct Widget
{
  void DoIt() const { /* do it */ }
};
 
void DoIt(const std::vector<Widget*>& v)
{
  const int sz = v.size();
  for (int i=0; i!=sz; ++i)
  {
    v[i]->DoIt();
  }
}

 

 

 

 

 

 

Question #7: Widget::DoItOften on Widget*

 

Replace the for-loop. You will need:

 

#include <vector>
 
struct Widget
{
  void DoItOften(const int n) const { /* do it n times */ }
};
 
void DoItOften(const std::vector<Widget*>& v, const int n)
{
  const int sz = v.size();
  for (int i=0; i!=sz; ++i)
  {
    v[i]->DoItOften(n);
  }
}

 

 

 

 

 

 

Question #8: GetSum

 

Replace the for-loop. You will need:

 

#include <vector>
 
const int GetSum(const std::vector<int>& v)
{
  const int sz = v.size();
  const int sum = 0;
  for (int i=0; i!=sz; ++i)
  {
    sum+=v[i];
  }
  return sum;
}

 

 

 

 

 

 

Question #9: Product

 

Replace the for-loop. You will need:

 

#include <vector>
 
const int Product(const std::vector<int>& v)
{
  const int sz = v.size();
  const int product = 1;
  for (int i=0; i!=sz; ++i)
  {
    product*=v[i];
  }
  return product;
}

 

 

 

 

 

 

Question #10: Widget::DoIt on boost::shared_ptr<Widget>

 

Replace the for-loop. You will need:

 

#include <vector>
#include <boost/shared_ptr.hpp>
 
struct Widget
{
  void DoIt() const { /* do it */ }
};
 
void DoIt(const std::vector<boost::shared_ptr<Widget> >& v)
{
  const std::size_t sz = v.size();
  for (std::size_t i=0; i!=sz; ++i)
  {
    v[i]->DoIt();
  }
}

 

 

 

 

 

 

Question #11: ReplaceZeroByOne

 

Replace the for-loop. You will need:

 

#include <vector>
 
void ReplaceZeroByOne(std::vector<int>& v)
{
  const int sz = v.size();
  for (int i=0; i!=sz; ++i)
  {
    if(v[i]==0) v[i]=1;
  }
}

 

 

 

 

 

 

Question #12: ReplaceNegativeByZero

 

Replace the for-loop. You will need:

 

#include <vector>
 
void ReplaceNegativeByZero(std::vector<int>& v)
{
  const int sz = v.size();
  for (int i=0; i!=sz; ++i)
  {
    if(v[i]<0) v[i]=0;
  }
}

 

 

 

 

 

 

Question #13: MakeAbs

 

Replace the for-loop. You will need:

 

#include <cmath>
#include <vector>
 
void MakeAbs(std::vector<int>& v)
{
  const int sz = v.size();
  for (int i=0; i!=sz; ++i)
  {
    v[i] = std::abs(v[i]);
  }
}

 

 

 

 

 

 

Question #14: MakeSquare

 

Replace the for-loop. You will need:

 

#include <vector>
 
void MakeSquare(std::vector<int>& v)
{
  const int sz = v.size();
  for (int i=0; i!=sz; ++i)
  {
    v[i]*=v[i];
  }
}

 

 

 

 

 

 

Question #15: CoutVector

 

Replace the for-loop. You will need:

 

#include <vector>
 
void CoutVector(std::vector<int>& v)
{
  const int sz = v.size();
  for (int i=0; i!=sz; ++i)
  {
    std::cout << v[i] << '\n';
  }
}

 

 

 

 

 

 

Question #16: Reciprocal

 

Replace the for-loop. You will need:

 

#include <vector>
 
void Reciprocal(std::vector<double>& v)
{
  const int sz = v.size();
  for (int i=0; i!=sz; ++i)
  {
    v[i]=1.0/v[i];
  }
}

 

 

 

 

 

 

Question #17: Halve

 

Replace the for-loop. You will need:

 

#include <vector>
 
void Halve(std::vector<double>& v)
{
  const int sz = v.size();
  for (int i=0; i!=sz; ++i)
  {
    v[i]/=2.0;
  }
}

 

 

 

 

 

 

Question #18: SumPositives

 

Replace the for-loop. You will need:

 

int SumPositives(const std::vector<int>& v)
{
  const size_t sz = v.size();
  int sum = 0;
  for (size_t i=0; i!=sz; ++i)
  {
    if (v[i]>0) sum+=v[i];
  }
  return sum;
}

 

 

 

 

 

 

Question #19: ProductNonZeroPositives

 

Replace the for-loop. You will need:

 

int ProductNonZeroPositives(const std::vector<int>& v)
{
  const size_t sz = v.size();
  int product = 0;
  for (size_t i=0; i!=sz; ++i)
  {
    if (v[i]>0) product*=v[i];
  }
  return product;
}

 

 

 

 

 

 

Question #20: CountNonZeroPositives

 

Replace the for-loop. You will need:

 

#include <vector>

int CountNonZeroPositives(const std::vector<int>& v)
{
  int sum = 0;
  const size_t sz = v.size();
  for (size_t i = 0; i!=sz; ++i)
  {
    if (v[i]>0) sum+=v[i];
  }
}

 

 

 

 

 

 

Post your feedback

 

Feel free to post your feedback about this exercise at Programmer's Heaven.

 

 

 

 

 

References

 

  1. Bjarne Stroustrup. The C++ Programming Language (3rd edition). ISBN: 0-201-88954-4. Chapter 18.12.1 : 'Prefer algorithms over loops'
  2. Herb Sutter and Andrei Alexandrescu. C++ coding standards: 101 rules, guidelines, and best practices. ISBN: 0-32-111358-6. Chapter 84: 'Prefer algorithm calls to handwritten loops.'

 

 

 

 

 

Go back to Richel Bilderbeek's C++ page.

Go back to Richel Bilderbeek's homepage.

 

Valid XHTML 1.0 Strict