snippetcppMinor
Using inputted data from vector to create two outputs
Viewed 0 times
inputtedcreatetwousingoutputsfromdatavector
Problem
I'm trying to figure out a way to do the exercise 3.20 in the C++ primer book
I have to create a program that reads input into a vector then use that data to create 2 outputs:
I've created the following code, but it feels off somehow. Can I simplify/clean up this stuff a bit?
I have to create a program that reads input into a vector then use that data to create 2 outputs:
- one is the sum of each adjacent number
- one is the sum of the first and last number moving inwards (as in the 2nd and 2nd last, 3rd and 3rd last etc)
I've created the following code, but it feels off somehow. Can I simplify/clean up this stuff a bit?
#include
#include
#include
#include
using std::cin; using std::cout; using std::endl; using std::vector; using std::string;
int main()
{
vector nv;
int n;
while (cin >> n)
{
nv.push_back(n);
}
int cnt = 0;
int output = 0;
int oldnum = 0;
//output sum of adjacent
for (int cn : nv)
{
output += cn;
output += oldnum;
++cnt;
if (cnt == 2)
{
cout << output << " ";
cnt = 1;
output = 0;
oldnum = cn;
}
}
cout << endl;
//output sum of first and last
int trigger = 1;
for (decltype(nv.size()) i = 0; i < (nv.size()/2); ++i)
{
cout << (nv[trigger - 1]) + (nv[nv.size() - (1 * trigger)]) << " ";
++trigger;
}
return 0;
}Solution
Although there's room for argument that it might be an abuse, one way you could do the adjacent sums part of this would be to use
Note, however, that the first result you get from this will be just the first item, not added to anything. Each subsequent value in the result will be the sum of the current and previous items.
You might consider, instead, implementing an
For the second part, I'd probably use
std::adjacent_difference, but pass it a function that adds instead of subtracts:std::adjacent_difference(inputs.begin(), inputs.end(),
std::ostream_iterator(std::cout, "\t"),
std::plus());Note, however, that the first result you get from this will be just the first item, not added to anything. Each subsequent value in the result will be the sum of the current and previous items.
You might consider, instead, implementing an
adjacent_sum that produces the result you want a little more directly:template
OutIt adjacent_sum(InIt begin, InIt end, OutIt result) {
++begin;
while (begin != end) {
*result = *begin + *(begin-1);
++result;
++begin;
}
return result;
}
// ...
adjacent_sum(inputs.begin(), inputs.end(),
std::ostream_iterator(std::cout, " "));For the second part, I'd probably use
std::transform, supplying forward iterators for the first range, and a reverse iterator for the beginning of the second range:std::transform(inputs.begin(), inputs.begin()+inputs.size()/2,
inputs.rbegin(),
std::ostream_iterator(std::cout, " "),
std::plus());Code Snippets
std::adjacent_difference(inputs.begin(), inputs.end(),
std::ostream_iterator<int>(std::cout, "\t"),
std::plus<int>());template <class InIt, class OutIt>
OutIt adjacent_sum(InIt begin, InIt end, OutIt result) {
++begin;
while (begin != end) {
*result = *begin + *(begin-1);
++result;
++begin;
}
return result;
}
// ...
adjacent_sum(inputs.begin(), inputs.end(),
std::ostream_iterator<int>(std::cout, " "));std::transform(inputs.begin(), inputs.begin()+inputs.size()/2,
inputs.rbegin(),
std::ostream_iterator<int>(std::cout, " "),
std::plus<int>());Context
StackExchange Code Review Q#54527, answer score: 4
Revisions (0)
No revisions yet.