Welcome. My problem is that I have given an array of numbers which I need to calculate the average (that part I did), but then I have to find the array element (module), which is closer to the average. Below paste the code (a form of main () imposed)
#include <iostream>
using namespace std;
double* aver(double* arr, size_t size, double& average){
double count;
for(int p = 0; p < size; p++)
count += arr[p];
count /= size;
double * pointer;
pointer = &count;
average = *pointer;
}
int main() {
double arr[] = {1,2,3,4,5,7};
size_t size = sizeof(arr)/sizeof(arr[0]);
double average = 0;
double* p = aver(arr,size,average);
cout << p << " " << average << endl;
}
The program should give a result
4 3.66667
I have no idea how to check which element is nearest to another, and substitute it into *p
I will be very grateful for any help.
Okay, this is not the answer to your problem, since you already got couple of them
How about trying something new ?
Use std::accumulate, std::sort and std::partition to achieve same goal.
#include<algorithm>
//...
struct comp
{
double avg;
comp(double x):avg(x){}
bool operator()(const double &x) const
{
return x < avg;
}
};
std::sort(arr,arr+size);
average =std::accumulate(arr, arr+size, 0.0) / size;
double *p= std::partition(arr, arr+size, comp(average));
std::cout<<"Average :"<<average <<" Closest : "<<*p<<std::endl;
This algorithm is based on the fact that std::map keeps its elements sorted (using operator<):
#include <map>
#include <iostream>
#include <math.h>
using namespace std;
double closest_to_avg(double* arr, size_t size, double avg) {
std::map<double,double> disturbances;
for(int p = 0; p < size; p++) {
disturbances[fabs(avg-arr[p])]=arr[p]; //if two elements are equally
} //distant from avg we take
return disturbances.begin()->second; //a new one
}
Since everybody is doing the kids homework...
#include <iostream>
using namespace std;
double min(double first, double second){
return first < second ? first : second;
}
double abs(double first){
return 0 < first ? first : -first;
}
double* aver(double* arr, size_t size, double& average){
double count;
for(int p = 0; p < size; p++)
count += arr[p];
average = count/size;
int closest_index = 0;
for(int p = 0; p < size; p++)
if( abs(arr[p] - average) <
abs(arr[closest_index] - average) )
closest_index = p;
return &arr[closest_index];
}
int main() {
double arr[] = {1,2,3,4,5,7};
size_t size = sizeof(arr)/sizeof(arr[0]);
double average = 0;
double* p = aver(arr,size,average);
cout << *p << " " << average << endl;
//Above ^^ gives the expected behavior,
//Without it you'll get nothing but random memory
}
I insist that you need the * before the p, it gives the value that the pointer is pointing too. Without the * then the value is the address of the memory location, which is indeterminate in this case. Ask your professor/teacher whether the specification is correct, because it isn't.
Try and understand the style and functions involved - it isn't complicated, and writing like this can go a long ways to making your graders job easier.
Also that interface is a very leaky one, in real work - consider some of the standard library algorithms and containers instead.
Related
I filled an array with 30 random numbers and calculated average. I want to display how many numbers are higher than the average. I tried making a function "aboveAverage" and check if the numbers are higher than the average and than just increase the count "num_over_average++". The problem is I don't know how to pass a value "avg" from function to another function.
#include <iostream>
#include <ctime>
using namespace std;
const int n = 30;
void fillArray(int age[], int n) {
srand(time(NULL));
for (int index = 0; index < n; index++) {
age[index] = (rand() % 81) + 8;
}
}
void printArray(int age[], int n) {
for (int index = 0; index < n; index++) {
cout << age[index] << endl;
}
}
double printAverage(int age[], int n) {
double sum;
double avg = 0.0;
for (int i = 0; i < n; i++) {
sum = sum + age[i];
}
avg = ((double) sum) / n;
cout << avg << endl;
return avg;
}
void aboveAverage(int age[], int n) {
double avg;
int num_over_average = 0;
for(int i = 0; i < n; i++){
if(age[i] > avg) {
num_over_average++;
}
}
cout<<num_over_average;
}
int main(int argc, char *argv[]) {
int age[n];
fillArray(age, n);
cout << "array: " << endl;
printArray(age, n);
cout << endl;
aboveAverage(age, n);
//example: Days above average: 16
}
This should be a comment, but I don't have enough reps :(
Change aboveAverage to void aboveAverage(int age[], int n, double avg)
Return avg from printAverage function
Change the last part of your main code to
double avg;
avg = printAverage(age, n);
aboveAverage(age, n, avg);
Hope this helps!
You have two solutions using your code:
Either you call printAverage() to initialise avg in aboveAverage() :
void aboveAverage(int age[], int n) {
double avg = printAverage();
...
}
Or you pass the average at parameter of aboveAverage() after having computed it with printAverage() :
void aboveAverage(int age[], int n, double avg) {
...
}
If you use the standard library you can do that with two lines of code:
double average = std::accumulate(std::begin(age), std::end(age), 0.0) / std::size(age);
int above_average = std::count_if(std::begin(age), std::end(age),
[average](double value) { return average < value; });
Okay, you might count that as three lines.
One major advantage of this approach over the code in the question is that you can change the container type to, say, vector<double> without having to change any of this code.
Well is pretty simple but dependent on your situation, I'll elaborate.
I'm the case when it's part of a bigger function (do-somthing())
You could calculate the average value like so and pass it to your "aboveAverage" function and print it:
double n_average = printAverage(nArr_ages, n_agesArraySize);
aboveAverage(nArr_ages, n_agesArraySize, n_averag);
Myself would probably rewrite the printAverage function as two functions, one that returns the average value based on the array and another that prints it not both at once because it violates the SOLID principals of a single responsibility and that a function name should reflect exactly what it does, in this case maybe calculateAverage or getAverageAge or any other appropriate name will do (try and name your functions like the english language so your code will be read like a song.
For example:
const size_t n = 30;
double calculateAverage(int nArr_ages[], int n_agesArraySize) {
double sum = 0.0;
double avg = 0.0;
for (int indexInArray = 0; indexInArray < n_agesArraySize; indexInArray++) {
sum = sum + age[indexInArray];
}
average = ((double) sum) / n_agesArraySize;
return average;
}
int aboveAverageCells(int ages[], int n_agesArraySize ) {
double average = calculateAverage(ages, n);
int num_over_average = 0;
for(int indexInArray = 0; indexInArray < n_agesArraySize; indexInArray++) {
if(ages[indexInArray] > avg) {
num_over_average++;
}
}
return num_over_average;
}
Now just call them in order, save the returned values to local variables in the main function and print using cout also locally in main.
As a side note next time maybe choose different names for the const and the local functions variable for the array size.
I really need help on learning how to convert arrays of different types to doubles (short, long, float). I'm not really sure how to ask the question any better. This is for an assignment for school. I understand that the assignment isn't complete, I just need to learn to do this before I continue to make arrays for short and long types.
Assignment Description:
We are going to expand program to account for different primitives. This implementation will implement all 8 functions described in program 2 as templates. To show this works, the main function will declare 4 different arrays that contain 10 values. The different arrays will be declared as shorts, longs, floats, and doubles. Each array will be filled with random values from a random-number generator. The array will be printed, then each of the 8 functions will be called and the results printed to the user. In order to provide a container, each of the functions will be part of a class called “MathHelper” that has all of the functions declared with a public access modifier and a static modifier.
MathHelper.h
#pragma once
class MathHelper
{
public:
static double calculateSum(const double numbers[], const int& count);
static double calculateAverage(const double numbers[], const int& count);
static int highestNum(const double numbers[], const int& count);
//int lowestNum(const int numbers[], const int& count);
//int numRange(const int numbers[], const int& count);
//double standardDeviation(const int numbers[], const int& count);
//int smallestFactorial(const int numbers[], const int& count);
};
MathHelper.cpp
#include "MathHelper.h"
MathHelper::MathHelper()
{
}
double MathHelper::calculateSum(const double numbers[], const int& count)
{
if (count <= 0)
return 0;
double total = 0;
for (int i = 0; i < count; i++)
total += numbers[i];
return total;
}
double MathHelper::calculateAverage(const double numbers[], const int& count)
{
if (count <= 0)
return 0;
return static_cast<double>(calculateSum(numbers, count)) / count;
}
int MathHelper::highestNum(const double numbers[], const int& count)
{
if (count <= 0)
return 0;
int highest = numbers[0];
for (int i = 1; i < count; ++i)
if (highest < numbers[i])
highest = numbers[i];
return highest;
}
MathHelper::~MathHelper()
{
}
Program4.cpp
// Program4Fix.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "MathHelper.h"
#include <iostream>
#include <cmath>
#include <ctime>
#include <iomanip>
int main()
{
const int size = 10;
double* myDoubles = new double[size];
float* myFloats = new double[size];
srand((unsigned)time(NULL));
// double fill
std::cout << std::endl;
std::cout << "Double Array: \n";
for (int i = 0; i < size; i++)
{
*(myDoubles + i) = rand() / double(RAND_MAX)*50.f + 1.f;
std::cout << i << ": " << std::setprecision(4) << *(myDoubles + i) << std::endl;
}
std::cout << std::setprecision(5) << "The sum of the numbers is: " << MathHelper::calculateSum(myDoubles, size) << "\n";
std::cout << std::setprecision(5) << "The average of the numbers is: " << MathHelper::calculateAverage(myDoubles, size) << "\n";
// long fill
std::cout << "Float Array: \n";
for (int i = 0; i < size; i++)
{
*(myFloats + i) = rand() / float(RAND_MAX)*50.f + 1.f;
std::cout << i << ": " << std::setprecision(4) << *(myFloats + i) << std::endl;
}
std::cout << std::setprecision(5) << "The sum of the numbers is: " << MathHelper::calculateSum(myFloats, size) << "\n";
std::cout << std::setprecision(5) << "The average of the numbers is: " << MathHelper::calculateAverage(myFloats, size) << "\n";
return 0;
}
I guess my real question is, is there anyway to use a value of type double* to initialize an entity of type float*?
const int size = 10;
double* myDoubles = new double[size]; // this works
float* myFloats = new double[size]; // this doesn't work, is there a way to do this similar to the one above?
Since you are asking about C++, don't use implicit conversion
double d = 1.5;
int i = d;
Also don't use c-style casting:
double d = 1.5;
int i = (int)d;
Make use of proper casting
int i = static_cast<int>(d);
You can read up on why, there are many reasons why to cast in C++.
For converting the array, you need to create a new array and then iterate over the existing one, convert one by one and then assign them to the new one.
For C++11 you can possibly use the std::transform() function.
I guess what you should do is generalize the functions in MathHelper to template functions which can be used for other types than double. I would get a decent C++ book and read about template functions, e.g. in A Tour of C++ or Programming -- Principles and Practice Using C++. You can get the first four chapters for the Tour of C++ from isocpp.org, and the second chapter introduces templates.
In the end, you should have code that looks like
class MathHelper
{
public:
template<typename T> static double calculateSum(const T numbers[], const int& count);
};
As a general remark, the posted code looks very C-ish meaning that it uses C-constructs where C++ has better alternatives, e.g. manually managed arrays instead of std::vector. You should avoid this.
Converting to double from float, int, or long is as simple as just assigning the source variable to a variable declared double.
For example:
int a = 1
long b = 2;
float c = 3.0f;
double result;
result = a;
result = b;
result = c;
In the 3 last statements, the values will be converted to doubles for you.
You can also convert the other way by casting.
const int size = 10;
double* myDoubles = new double[size];
float* myFloats = new float[size];
InitializeArray(myDoubles); // You'll have to start with some values
for(int i = 0; size > i; ++i)
{
myFloats[i] = (float) myDoubles[i];
}
I suppose to calculate the average in the array of doubles then return the value of the closest element in the array to the calculated average. But the algorithm I used is O(2n). Is it possible to determine the closest element to the average while still calculating average?
I think no.
#include <iostream>
#include <cmath>
using namespace std;
double* aver(double* arr, size_t size, double& average){
for(int i = 0; i < size; i++)
average+=arr[i];
average/=size;
double* ret = arr;
for(int i = 0; i < size; i++){
if(abs(arr[i] - average) < abs(*ret - average)){
*ret = arr[i];
}
}
return ret;
}
int main(){
double arr[] = {1,2,3,4,5,7};
size_t size = sizeof(arr)/sizeof(arr[0]);
double average = 0;
double* p = aver(arr, size, average);
cout<< *p << " " << average << endl;
return 0;
}
You can find an element closest to a target with a trivial O(logn) binary search if the array is sorted. If it's not sorted, then it's a linear search.
As a side note, O(2n) might make intuitive sense, but mathematically speaking it's no different than O(n).
Under the premise of exclusively non-negative values in the array, you might use this adaption of your code:
#include <iostream>
#include <cmath>
using namespace std;
double* aver(double* arr, size_t size, double& average){
int iclosest = 0;
for(int i = 0; i < size; i++) {
average+=arr[i];
if (abs(arr[iclosest + 1] - average/(i+1)) < abs(arr[iclosest] - average/(i+1)))
++iclosest;
}
average/=size;
return &arr[iclosest];
}
int main(){
//double arr[] = {1,2,3,4,5,7};
double arr[] = {4,5,3,2,1,7};
size_t size = sizeof(arr)/sizeof(arr[0]);
double average = 0;
double* p = aver(arr, size, average);
cout<< *p << " " << average << endl;
return 0;
}
It can be adapted to work with negative values, either.
But that said, I concur with Blindy as far as O(2n) = O(n) is concerned.
I made a recursive function to find the max and min value from an array which may contain arbitrary number of elements. The main reason behind making this was to develop an idea in finding the min max value from the pixel data of a Dicom image. I made this recursive function as a test code where I filled an int type array with random numbers ranging from 0-1000. My code is as below. I presented the whole code, you can run the program very easily in Visual Studio yourself.
#include <stdio.h>
#include <string>
#include <iostream>
#include <math.h>
#include <time.h>
using namespace std;
void recursMax(int* a, int size, int* maxValue)
{
int half = size/2;
int* newMax = new int[half];
for(int i=0; i<half; i++)
{
newMax[i]=a[i]>a[size-i-1]?a[i]:a[size-i-1];
}
if(half>1)
{
recursMax(newMax, half, maxValue);
}
if(half == 1)
{
*maxValue = newMax[0];
delete [] newMax;
}
}
void recursMin(int* a, int size, int* minValue)
{
int half = size/2;
int* newMin = new int[half];
for(int i=0; i<half; i++)
{
newMin[i]=a[i]<a[size-i-1]?a[i]:a[size-i-1];
}
if(half>1)
{
recursMin(newMin, half, minValue);
}
if(half == 1)
{
*minValue = newMin[0];
delete [] newMin;
}
}
int main ()
{
int size = 100;
int* a = new int[size];
srand(time(NULL));
for(int i=0; i<size; i++)
{
a[i]=rand()%1000;
cout<<"Index : "<<i+1<<", "<<a[i]<<endl;
}
cout<<endl<<endl<<"Now we look to find the max!"<<endl;
int maxValue = 0;
int minValue = 0;
recursMax(a, size, &maxValue);
cout<<maxValue<<endl;
recursMin(a, size, &minValue);
cout<<"Now we look for the min value!"<<endl<<minValue<<endl;
cout<<"Checking the accuracy! First for Max value!"<<endl;
for(int i=0; i<size; i++)
{
cout<<"Index : "<<i+1<<", "<<maxValue-a[i]<<endl;
}
cout<<"Checking the accuracy! Now for min value!"<<endl;
for(int i=0; i<size; i++)
{
cout<<"Index : "<<i+1<<", "<<a[i]-minValue<<endl;
}
delete [] a;
return 0;
}
My question to you is that, do you think my algorithm works correctly? I'm have some doubt. Also, am I handling or maintaining the memory correctly? Or there will be some memory leakage in the code?
You should take delete [] newMax; out of last if statement, otherwise you'll never free memory. Like this:
if(half == 1)
{
*maxValue = newMax[0];
}
delete [] newMax;
And the same for recursMin function.
Your algorithm seems working, but excessive. Using recursion and allocating memory just to find min and max is not a good style.
For the max value I'd go with something like this:
int ArrayMax(const int *begin, const int *end)
{
int maxSoFar = *begin; // Assume there's at least one item
++begin;
for(const int *it = begin; it!=end; ++it)
{
maxSoFar = std::max(maxSoFar, *it);
}
return maxSoFar
}
Now you can say:
int main ()
{
int size = 100;
int* a = new int[size];
srand(time(NULL));
for(int i=0; i<size; i++)
{
a[i]=rand()%1000;
cout<<"Index : "<<i+1<<", "<<a[i]<<endl;
}
int theMax = ArrayMax(a, a+size);
}
Needless to say, you can convert ArrayMax into a template function to take any type, and ArrayMin is easily implemented using the same pattern.
I would suggest this code for finding the minimum, maximum is similar:
int min = std::numeric_limits<int>::max();
for(int i = 0; i < size ; i++) min = std::min(min,a[i]);
A lot shorter, no memory allocation, easy loop so the compiler will probably 1) vectorize it for maximum speed 2) use correct prefetching for even higher speed.
Only a partial answer because I haven't verified the algorithm in detail, but you're much better off copying the array first, then using that copy destructively to store your values.
It might use more memory, but saves you both runtime and bug chasing time on memory management.
You could probably improve things with an iterative implementation rather than a recursive one, if you risk running into degerate case that cause too deep recursion.
Using algorithm from STL:
Since C++11: you may use std::minmax_element to retrieve both at once : https://ideone.com/rjFlZi
const int a[] = {0, 1, 42, -1, 4};
auto it = std::minmax_element(std::begin(a), std::end(a));
std::cout << *it.first << " " << *it.second << std::endl;
In C++03, you may use std::min_element and std::max_element.
This is terrible algorithm for finding minimum and maximum. You can use simpler, shorter and faster solution:
const int maxInArray( const int* beg, const int* end) {
const int* it = std::max_element( beg, end);
if ( it == end)
{
std::cout << "There is no smallest element" << std::endl;
}
else
{
std::cout << "The smallest element is " << *it << std::endl;
}
return *it;
}
or iterate over the array:
int maxInArray( const int* beg, const int* end) {
int max;
if ( end - beg < 1 ) return -1;
max = *beg
while ( beg++ != end) {
if ( *beg > max) max = *beg;
}
return max;
}
with no boost support:
#include <iostream>
#include <limits>
int main() {
int max = std::numeric_limits<int>::min();
int min = std::numeric_limits<int>::max();
int num;
while ( std::cin >> num) {
if (num > max) {
max = num;
}
if (num < min) {
min = num;
}
}
std::cout << "min: " << min << std::endl;
std::cout << "max: " << max << std::endl;
return 0;
}
or with help from boost:
#include <iostream>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/min.hpp>
#include <boost/accumulators/statistics/max.hpp>
using namespace boost::accumulators;
int main() {
// Define an accumulator set for calculating the mean, max, and min
accumulator_set<double, features<tag::min, tag::max> > acc;
int num = -1;
bool empty = true;
while ( std::cin >> num && num >= 0) {
empty = false;
acc( num);
}
if ( ! empty) {
// Display the results ...
std::cout << "Min: " << min( acc) << std::endl;
std::cout << "Max: " << max( acc) << std::endl;
}
return 0;
}
Basically finding max in array is not recommended by recursion as it is not required. Divide and conquer algorithms(recursive) are more time costly. But even though if you want to use it, you can use my below algorithm. Basically, it brings the largest element of array at first position and has almost linear running time.(This algo is just a recursive-illusion though!):
int getRecursiveMax(int arr[], int size){
if(size==1){
return arr[0];
}else{
if(arr[0]< arr[size-1]){
arr[0]=arr[size-1];
}
return(getRecursiveMax(arr,size-1));
}
}
I'm trying to create a program that will display bar graphs with * the maximum number of * can be 40. I have everything working but had a question with the code. Is there a better way as you can see I have to go back to the original address twice using:
p_bar_length = p_bar_length - size;
Is there a better way to do this?
#include <iostream>
using namespace std;
const int MAX_SPLATS = 40;
void bar_chart(double values[], int size)
{
double largest = values[0]; //assign first element to be the largest
//Find the largest value
for (int i = 1; i < size; i++)
{
if (largest < values[i]) // check to see if there is something larger
{
largest = values[i];
}
}
// Find the number of spalts to use
// with the precent based on the largest value
int* p_bar_length = new (nothrow) int[size];
for (int i = 0; i < size; i++)
{
*p_bar_length = (values[i] / largest) * MAX_SPLATS;
p_bar_length++; // Go to next memory address
}
// Go back to the orignal memory address
p_bar_length = p_bar_length - size;
// Pritnt the correct number of splats
for (int i = 0; i < size; i++)
{
for (int j = 0; j < *p_bar_length; j++)
{
cout << "*";
}
p_bar_length++;
cout << endl;
}
// Go back to the orignal memory address
p_bar_length = p_bar_length - size;
delete[] p_bar_length;
}
int main()
{
double values[6] = { 22, 40, 28, 26, 14, 46};
int val_size = 6;
bar_chart(values, val_size);
system("pause");
return 0;
}
Since this is C++, the best way is not to use pointers; instead, use a std::vector.
That said, you can also always treat a pointer as an array and just access p_bar_length[i] for a given position 0 <= i < length instead of incrementing the pointer.
Rather than incrementing the pointer, use the array index:
p_bar_length[i] = (values[i] / largest) * MAX_SPLATS;
or use pointer arithmetic:
*(p_bar_length + i) = (values[i] / largest) * MAX_SPLATS;
You do not need the first for loop if you use std::max_element from <algorithm>.
You do not need the second for loop if you calculate the bar length in the third for loop.
Something like this:
void bar_chart(double values[], int size)
{
//Find the largest value
double largest = *std::max_element(values, values + size);
// Print the correct number of splats
for (int i = 0; i < size; i++)
{
int p_bar_length = (values[i] / largest) * MAX_SPLATS;
cout << string(p_bar_length, '*') << endl;
}
}
That way you don't need the p_bar_length array at all. It is only a simple int.
Edit: And you could even replace the inner for loop (example modified)
Since you tagged this as C++ I would recommend using the standard library.
Your program is more C than C++, but if c is ok for you there is not much to improve.
On the other hand, using vector and algorithm you don't need to mess around with pointers. And using C++11 it removes the rough edges previously associated with templates and iterators.
A quick shot:
#include <iostream>
#include <vector>
#include <algorithm>
const int MAX_SPLATS = 40;
template <typename C>
void bar_chart(const C& values)
{
if (std::distance(values.begin(), values.end())<1)
return; // do some error handling
auto largest = *std::max_element(values.begin(), values.end());
// Find the number of splats to use with the percent based on
// the largest value
std::vector<int> bars(values.size());
std::transform(values.begin(), values.end(), bars.begin(),
[=] (double d) { return (d/largest)*MAX_SPLATS; });
// Print the correct number of splats
std::for_each(bars.begin(), bars.end(),
[](int val){ std::cout << std::string(val, '*') << std::endl; });
}
int main()
{
std::vector<double> values = { 22, 40, 28, 26, 14, 46 };
bar_chart(values);
std::cin.get();
return 0;
}
Make another copy of the pointer to use within your loop. Much less error prone.
int* p_bar_length = new (nothrow) int[size];
int* p = p_bar_length;
for (int i = 0; i < size; i++)
{
*p = (values[i] / largest) * MAX_SPLATS;
p++; // Go to next memory address
}
P.S. Why are you using nothrow? Since you're not checking the value you get back from new, an exception will be much nicer than the mess you'll have when you get back a NULL pointer.
You could treat p_bar_length as an array and just use consistent notation
int* p_bar_length = new (nothrow) int[size];
for (int i = 0; i < size; i++)
{
p_bar_length[i] = (values[i] / largest) * MAX_SPLATS;
}
How about two in one?
int* p_bar_length = new (nothrow) int[size];
for (int i = 0; i < size; i++)
{
*p_bar_length = (values[i] / largest) * MAX_SPLATS;
for (int j = 0; j < *p_bar_length; j++) cout << "*";
cout << endl;
p_bar_length++; // Go to next memory address
}
This is rather similar to the post from #mkaes, but goes one step further. Instead of using std::transform to create a vector of the proper lengths, then std::for_each to create a string the proper length from each of those, this creates a string directly from the input, and writes the strings directly from std::transform:
#include <iostream>
#include <array>
#include <algorithm>
#include <string>
#include <iterator>
const int MAX_SPLATS = 40;
template <typename C>
void bar_chart(const C& values)
{
if (std::distance(values.begin(), values.end())<1)
return; // do some error handling
auto largest = *std::max_element(values.begin(), values.end());
std::transform(values.begin(), values.end(),
std::ostream_iterator<std::string>(std::cout, "\n"),
[=](double d) { return std::string((d/largest)*MAX_SPLATS, '*');} );
}
int main() {
std::array<double, 6> values = {22, 40, 28, 26, 14, 46};
bar_chart(values);
return 0;
}
Since it's using C++11 anyway, I decided to also use an std::array since it seems to fit nicely for the job at hand.