In today's lesson, we'll explore a comprehensive problem using the Boost.Range library in C++. Completing this lesson will help you understand how to use ranges to solve complex tasks systematically. Our goal is to calculate the average price of houses that cost more than 50,000 by filtering, transforming, and accumulating values—operations that Boost.Range simplifies tremendously.
Imagine you have a dataset filled with house prices. Our task is to find the average price of these houses, but only for those that cost more than 50,000. This problem involves multiple steps: filtering out houses costing 50,000 or less, applying a 10% discount to each remaining house price, and then calculating the average price. Let's see how we can achieve this efficiently with Boost.Range.
First, we'll introduce the necessary libraries and set up our data. Here's a code snippet for reference:
C++1#include <iostream> 2#include <vector> 3#include <boost/range/adaptor/filtered.hpp> 4#include <boost/range/adaptor/transformed.hpp> 5#include <boost/range/numeric.hpp> 6 7int main() { 8 std::vector<int> house_prices = {45000, 52000, 61000, 49000, 75000, 80000}; 9}
A vector is a dynamic array that can grow as needed, making it suitable for storing integer prices. The given array contains both houses costing more and less than 50,000.
Next, we need to filter out the houses costing 50,000 or less. Boost.Range provides the boost::adaptors::filtered
functionality to achieve this:
C++1house_prices | boost::adaptors::filtered([](int price) { return price > 50000; })
Here, boost::adaptors::filtered
uses a lambda function to filter out prices less than or equal to 50,000. The lambda function [](int price) { return price > 50000; }
returns true
for prices greater than 50,000, allowing them to pass through the filter.
Once filtered, we want to apply a 10% discount to the remaining prices. This is done using boost::adaptors::transformed
:
C++1house_prices | boost::adaptors::filtered([](int price) { return price > 50000; }) 2 | boost::adaptors::transformed([](int price) { return price * 0.90; })
The transformation uses another lambda function, [](int price) { return price * 0.90; }
, which applies a 10% discount to each filtered price. We use the pipe operator to combine them
Finally, we need to sum the discounted prices and calculate the average price. For this, we use boost::accumulate
, which reduces the range to a single value starting with 0.0
:
C++1auto discounted_total = boost::accumulate( 2 house_prices | boost::adaptors::filtered([](int price) { return price > 50000; }) 3 | boost::adaptors::transformed([](int price) { return price * 0.90; }), 4 0.0 // Initial value for accumulate 5); 6 7auto house_count = boost::distance(house_prices | boost::adaptors::filtered([](int price) { return price > 50000; })); 8double average_price = discounted_total / house_count;
Here, boost::accumulate
takes the transformed range and sums the elements, starting from 0.0
. We also calculate the number of houses that cost more than 50,000 using boost::distance
and finally compute the average price by dividing the total discounted price by the count of filtered houses.
Let's combine everything in the main function:
C++1#include <iostream> 2#include <vector> 3#include <boost/range/adaptor/filtered.hpp> 4#include <boost/range/adaptor/transformed.hpp> 5#include <boost/range/numeric.hpp> 6 7int main() { 8 std::vector<int> house_prices = {45000, 52000, 61000, 49000, 75000, 80000}; 9 10 // Use boost::adaptors for filtering and transforming 11 auto discounted_total = boost::accumulate( 12 house_prices | boost::adaptors::filtered([](int price) { return price > 50000; }) // Filter houses costing more than 50000 13 | boost::adaptors::transformed([](int price) { return price * 0.90; }), // Apply a 10% discount 14 0.0 // Initial value for accumulate 15 ); 16 17 auto house_count = boost::distance(house_prices | boost::adaptors::filtered([](int price) { return price > 50000; })); 18 double average_price = discounted_total / house_count; 19 20 std::cout << "Average price of discounted houses: " << average_price << std::endl; // Output: Average price of discounted houses: 60300 21 22 return 0; 23}
By understanding each part separately, you can see how they work together to solve a complex problem efficiently.
In this lesson, we tackled a comprehensive problem using Boost.Range. We learned to filter a range to keep only house prices greater than 50,000, transform these prices by applying a 10% discount, and then calculate the average price. This exercise showcases the power of Boost.Range in writing clean, readable, and efficient C++ code.
Now it's time to apply what you've learned. You'll move on to exercises where you'll solve similar range-based problems using Boost.Range. This hands-on practice will reinforce your understanding and help you become proficient in using Boost.Range for real-world C++ programming tasks.