3

I'm new to C++ and hence would need some help in accomplishing a certain task. The problem is, I have to iterate over three or more vectors simultaneously, like so:

#include <vector>
#include <iostream>
#include <string>
#include <boost/range/combine.hpp>

using namespace std;


int main(int, char**) {

vector<string> questions = {"Planet", "Rocket", "Galaxy"};
vector<string> answers = {"Planet", "Saturn", "Star"};

vector<int> count = { 12, 34, 79};
vector<int> score = { 324, 956, 289};

vector<int> result;
vector<int> subscore;

string a, q;
int c, s;
for ( const string q : questions ) {
    int match = 0;
    for( auto tuple : boost::combine(answers, count) ) {
       boost::tie(a,c) = tuple;
       if( q.substr(0,2) == a.substr(0,2)) {std::cout << q.substr(0,3) << " " << a.substr(0,3) << endl; match = c;  }
       else cout << "No match!" << '\n';
            }
    if( match ) { result.push_back(match); }
    else result.push_back(0); subscore.push_back(0);

This approach works but I can't use it in the framework we are using.

Maybe someone here can point me to a similar solution that does not depend on boost but is still efficient.

Many thanks!

Number42
  • 133
  • 2
  • 10

2 Answers2

3

You can use good old index:

auto size = std::min( answers.size(), count.size() ); // or at least assert that size is equal
for( size_t i = 0; i < size; ++i ) {
   const auto &a = answers[i];
   const auto c = count[i];
   // .. same as before

note this way you possibly avoiding to make 2 copies of std::string per iteration - answers -> tuple -> a

Slava
  • 43,454
  • 1
  • 47
  • 90
1

This seems a transform so in C++ you can use std::transform... for example:

#include <vector>
#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

int main(int, char**) {
    vector<string> questions = {"Planet", "Rocket", "Galaxy"};
    vector<string> answers = {"Planet", "Saturn", "Star"};

    vector<int> count = { 12, 34, 79};

    vector<int> result;

    for(const auto& q : questions)
    {
        transform(begin(answers), end(answers), begin(count), back_inserter(result),
                  [&q](const auto& answer, auto count)
        {
            if (q.substr(0, 2) == answer.substr(0, 2))
            {
                std::cout << q.substr(0,3) << " " << answer.substr(0,3) << endl;
                return count;
            }
            else
                cout << "No Match!" << endl;

            return 0;
        });
    }
}

Now the results vector holds all results. back_inserter is used in order to dynamically grow the result std::vector.

Elvis Dukaj
  • 7,142
  • 12
  • 43
  • 85