-3

I have a map defined as follows:

const map<int, vector<float> >& m = …;

enter image description here

I want to loop over the columns (size of the map.second: vector) and in every iteration I get the:

1- The max value of the column across the map.first: int

2- The value of the map.first: int at the which the max occurs

For example:

#0 I get 31, 1

#1 I get 15, 2

#2 I get 18, 2

What is the easiest way to do this?

AhmedTE
  • 23
  • 5
  • 1
    what did you try? – Jeffrey Feb 02 '21 at 21:19
  • 2
    You should consider providing your coding efforts into this question. – Rohan Bari Feb 02 '21 at 21:20
  • This is really easy with an explicit for loop (nested two deep), and at first glance it looks very difficult to make a map/reduce sort of chain do it, especially if not all the contained vectors are guaranteed equal in length. So write the for loop. – Ben Voigt Feb 02 '21 at 21:21
  • 1
    The dupe closure was wrong, sorry about that. I've reopened. – cigien Feb 02 '21 at 21:24
  • I am not sure how to combine the first element of all vectors to together and then find the max across them. What would be the iterator of the first loop and second loops? – AhmedTE Feb 02 '21 at 21:33
  • 1
    Are all the vectors the same size or can they vary? – Jerry Jeremiah Feb 02 '21 at 21:35
  • yes, they all same size – AhmedTE Feb 02 '21 at 21:36
  • 1
    What about something like this: https://onlinegdb.com/Yd7yn5cJU – Jerry Jeremiah Feb 02 '21 at 22:02
  • 1
    @JerryJeremiah Why not write that up as an answer? – cigien Feb 03 '21 at 04:39
  • 1
    @cigien I was waiting to see if the OP had a comment. For example, I used C++ specific stuff that they might not be able to use. If the OP had commented that it had worked for them I would have made an answer. I guess I will just assume it answers their question adequately and make an answer anyway but usually that ends up with downvotes. I always figured it was better to be sure you had actually answered their question before making it an answer. – Jerry Jeremiah Feb 03 '21 at 04:44
  • 1
    @JerryJeremiah Unless the OP explicitly points out features they can't use, there's no issue in using them. Note that the post will be read by future visitors as well, not just the OP. It's up to you if you want to risk downvotes, but your solution seems correct to me. I wouldn't worry about it :) – cigien Feb 03 '21 at 04:46
  • @JerryJeremiah: That is perfect, thanks very much for your help, really appreciate it! – AhmedTE Feb 03 '21 at 15:09

1 Answers1

1

You need a function that accepts a column number and loops through each row calculating the maximum for that column.

You only need one loop because you can access whichever column you want by indexing the vector like an array (as long as you check that the vector has enough elements)

There are two ways to do this: the C++17 way where you can assign objects with multiple values directly to multiple variables, and the old way where you reference the members of std::pair instead.

The C++17 way:

#include <map>
#include <vector>
#include <utility>
#include <iostream>

std::pair<int,float> column_max(const auto & m, int column)
{
    int index = -1;
    float maximum = -std::numeric_limits<float>::max();
    for (const auto & [key,value] : m)
        if (value.size() > column && value[column] > maximum)
        {
            index = key;
            maximum = value[column];
        }
    return {index,maximum};
}


int main()
{
    const std::map<int,std::vector<float>> m =
    {
        {0, { 1,  5, 10, 22}},
        {1, {31,  5, 10, 12}},
        {2, { 1, 15, 18, 12}}
    };

    for (int i=0; i<4; i++)
    {
        const auto [index,maximum] = column_max(m,i);
        std::cout << "#" << i << ": " << maximum << " " << index << "\n";
    }
    
    return 0;
}

Try it here: https://onlinegdb.com/O5dmPot34

And the equivalent, but older way:

#include <map>
#include <vector>
#include <utility>
#include <iostream>
#include <float.h>

std::pair<int,float> column_max(const std::map<int,std::vector<float>> & m, int column)
{
    int index = -1;
    float maximum = -FLT_MAX;
    for (std::map<int,std::vector<float>>::const_iterator entry=m.begin(); entry!=m.end(); entry++)
        if (entry->second.size() > column && entry->second[column] > maximum)
        {
            index = entry->first;
            maximum = entry->second[column];
        }
    return std::make_pair(index,maximum);
}


int main()
{
    const std::map<int,std::vector<float>> m =
    {
        {0, { 1,  5, 10, 22}},
        {1, {31,  5, 10, 12}},
        {2, { 1, 15, 18, 12}}
    };

    for (int i=0; i<4; i++)
    {
        std::pair<int,float> value = column_max(m,i);
        std::cout << "#" << i << ": " << value.second << " " << value.first << "\n";
    }
    
    return 0;
}

Try it here: https://onlinegdb.com/273dnHRZK

Jerry Jeremiah
  • 9,045
  • 2
  • 23
  • 32