简体   繁体   中英

Printing the key value pairs of a map where the key is a vector in C++

I have a 2d vector that represents the points on a graph. I'm trying to find the Euclidean distance between these points from the origin.

Here is my code:

My idea is to map the points as a vector as a key to its Euclidean distance as a value. I was able to do it but I'm unable to print the map with key value pair. How can I print the map to see the values

#include <iostream>
#include <algorithm>
#include <vector>
#include <unordered_map>
#include <map>
#include <string>
#include <numeric>
#include <set>
#include <unordered_set>

using namespace std;

int main()
{
    vector<vector<int>> points = { {3,3},{5,-1},{-2,4} };

    unordered_map<vector<int>, double> mp;

    //for loop to find euclidean distance of each data point and then insert into map
    for (int i = 0; i < points.size(); i++)
    {
        int sum = 0;
        vector<int> alpha;  //temporary vector to store the data points 
        
        for (int j = 0; j < points[i].size(); j++)
        {
            sum = sum + (points[i][j] * points[i][j]);
            alpha.push_back(points[i][j]);
        }
        double res = sum;
        res = sqrt(res); //finding sqrt for euclidean distance
        mp.insert({ alpha, res });  //inserting into the map
        alpha.clear();
    }
  
    //Trying to print the map but isn't working
    for (auto itr = mp.begin(); itr != mp.end(); ++itr) {
        cout << itr->first
            << '\t' << itr->second << '\n';
    }

    return 0;
}

Error: C2679 binary '<<': no operator found which takes a right-hand operand of type '_Ty1' (or there is no acceptable conversion)

First, there is no hash function for std::vector key so you need to use std::unordered_map other way around:

std::unordered_map<double, std::vector<int>> mp;

and you could have a separate function for printing out elements of std::vector since operator<< is not overloaded for std::vector type:

template <typename T>
void print_vec(std::vector<T> const& v) {
    bool is_first{ true };
    std::cout << "{ ";
    for (auto const i : v) {
        if (is_first) {
            is_first = false;
            std::cout << i;
        } else {
            std::cout << ", " << i;
        }
    }
    std::cout << " }";
}

and then:

for (auto const& it : mp) {
    cout << it.first << '\t';
    print_vec(it.second);
    cout << '\n';
}

You can define an << for vector s, or write it inline in your printing of the map.

for (auto & [vec, sum] : mp) {
    for (auto & point : vec) {
        std::cout << point << " "
    }
    std::cout << '\t' << sum << '\n';
}

You will also need to define a Hash for vector to use it as the key of your map.

template <typename T, typename ElemHash = std::hash<T>>
struct sequence_hash {
    template <typename C>
    std::size_t operator()(const C & container) {
        std::size_t res = size_hash(container.size());
        for (auto & v : container) { 
            /* some combiner */
            boost::hash_combine(res, elem_hash(v)); 
        }
        return res;
    }

private:
    std::hash<std::size_t> size_hash;
    ElemHash elem_hash;
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM