HiveBrain v1.2.0
Get Started
← Back to all entries
snippetcppMinor

Using inputted data from vector to create two outputs

Submitted by: @import:stackexchange-codereview··
0
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:

  • 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 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.