1

I have 2 vectors of ints.

say the first one has (2,1). and the second one (1,1).

I am trying to subtract numbers like this:

2 - 1, 1 - 1

then I need to add these 2 numbers so the final answer would be 1.

I've tried a for loop, but it's subtracting each number from each element, instead of only the first one.

This is what I've tried so far.

vector<int> temp;

for(unsigned i =0; i < Vec1.size(); i++)
 for(unsigned o =0; o < Vec2.size(); o++)
   temp.push_back(Vec1.at(i).nums- Vec2.at(o).nums);

//where nums, are just the numbers showed above

The output as you would expect is : 1

1

0

0

and I need it to be:

1

0

then I can just do a for loop to add all the ints together.

Any help, would be greatly appreciated!

Hugs
  • 65
  • 5
  • idt you need another data structure here, you can do this in one go like `result += Vec1.at(i).nums- Vec2.at(o).nums` – roottraveller Nov 02 '19 at 07:09
  • @roottraveller That would output 2, it should be just 1, my problem here is that each element is being subtracted from every other element in Vec2, and I only want it to subtract the first element from Vec2. – Hugs Nov 02 '19 at 07:21

3 Answers3

4

I've tried a for loop, but it's subtracting each number from each element, instead of only the first one.

You are not doing it the right way. You have been using cascaded for loops and hence, you are subtracting each element of first vector from each element of second vector.

There are two ways to correctly implement:

One involves writing your own functions to subtract two vector and then adding elements of the result.

#include <iostream>
#include <vector>


std::vector<int> subtract(const std::vector<int>& a, const std::vector<int>& b)
{
    std::vector<int> result;
    const int SIZE = std::min(a.size(), b.size());

    for (int i = 0; i < SIZE; i++)
        result.push_back(a[i] - b[i]);

    return result;
}


int addAllElements(const std::vector<int>& a)
{
    int result = 0;
    for (auto i: a)
        result += i;
    return result;
}


int main(void)
{
    std::vector<int> a = {2, 1};
    std::vector<int> b = {1, 1};

    std::cout << "Result is " << addAllElements(subtract(a, b)) << std::endl;

    return 0;
}

The other method (preferred) involves using STL:

#include <iostream>

#include <vector>
#include <algorithm>
#include <numeric>

int main(void) 
{
    std::vector<int> a = { 2, 1 };
    std::vector<int> b = { 1, 1 };

    std::vector<int> result;
    std::transform(std::begin(a), std::end(a), std::begin(b), std::back_inserter(result), [](const auto a, const auto b) 
        {
            return a - b;
        } 
    );

    int sumAllElements = std::accumulate(result.begin(), result.end(), 0);
    std::cout << "Result is " << sumAllElements << std::endl;

    return 0;
}

The above code uses lambda expression. To know more about them, see this link.

std::accumulate sums all the elements of the container and std::transform performs the transformation (specified in it's fifth argument) on two vectors and put the result in a different vector. We have used lambda expression to perform the required sub operation.

EDIT:

To implement it without lambda is also easy. You can use function pointers.

#include <iostream>

#include <vector>
#include <algorithm>
#include <numeric>

double subtract(const double a, const double b)
{
    return a - b;
}

int main(void) 
{
    std::vector<int> a = { 2, 1 };
    std::vector<int> b = { 1, 1 };

    std::vector<int> result;
    std::transform(std::begin(a), std::end(a), std::begin(b), std::back_inserter(result), subtract);

    int sumAllElements = std::accumulate(result.begin(), result.end(), 0);
    std::cout << "Result is " << sumAllElements << std::endl;

    return 0;
}

There are various advantages of using lambda expression.

NOTE:

You can also use std::minus instead of defining you own function. Like this:

std::transform(std::begin(a), std::end(a), std::begin(b), std::back_inserter(result), std::minus<int>());
abhiarora
  • 9,743
  • 5
  • 32
  • 57
3

In C++17, you can combine std::transform and std::reduce/std::accumulate calls with std::transform_reduce:

const std::vector<int> vec1 {2, 1};
const std::vector<int> vec2 {1, 1};
auto res = std::transform_reduce(vec1.begin(), vec1.end(),
                                 vec2.begin(),
                                 0,
                                 std::plus<>(),
                                 std::minus<>());

Demo

Jarod42
  • 203,559
  • 14
  • 181
  • 302
2

Here is an example using the STL:

#include <algorithm>
#include <iostream>
#include <numeric>
#include <vector>

int main() {
    std::vector<int> vec1 {2, 1};
    std::vector<int> vec2 {1, 1};
    std::vector<int> temp;
    std::transform(begin(vec1), std::end(vec1), std::begin(vec2),
        std::back_inserter(temp), [](const auto a, const auto b) {return a - b;});
    auto sum = std::accumulate(temp.begin(), temp.end(), 0);
    std::cout << "Result: " << sum << "\n";
    return 0;
}
Håkon Hægland
  • 39,012
  • 21
  • 81
  • 174