简体   繁体   English

如何访问 map 的值<string, vector<int> &gt; 在 C++ 中?</string,>

[英]How to access the values of a map<string, vector<int>> in C++?

I am working on my version of a genetic algorithm to solve the knapsack problem in C++.我正在研究我的遗传算法版本,以解决 C++ 中的背包问题。 I have a map of string to vector like我有一个字符串到矢量的 map

map<string, vector<int>> objects
{
    {"Object 1", {7, 20, 15}},
    {"Object 2", {3, 50, 10}},
    {"Object 3", {5, 80, 12}},
    {"Object 4", {4, 80, 8}},
    {"Object 5", {2, 40, 11}}
};

and a vector of vectors和一个向量的向量

vector<vector<int>> population;

where I will store information such as我将在哪里存储信息,例如

population[0] = {0, 0, 1, 1, 0};
population[1] = {1, 0, 0, 0, 1};
population[2] = {1, 0, 1, 0, 1};
...

Each vector is called an individual , and each element of a given individual indicates the presence ( 1 ) or the absence ( 0 ) of the corresponding object.每个向量称为individual ,给定个体的每个元素表示对应的 object 的存在 ( 1 ) 或不存在 ( 0 )。 So, for example, the third individual ( population[2] ) has Object 1 , Object 3 and Object 5 .因此,例如,第三个人 ( population[2] ) 具有Object 1Object 3Object 5

What I want to do is write a function which will receive an index from population and return the sum of the corresponding values from objects .我想要做的是编写一个 function 它将接收来自population的索引并返回来自objects的相应值的总和。 In the case of population[2] I'd like to have another vector containing {14, 140, 38} ( 7+5+2, 20+80+40, 15+12+11 ).population[2]的情况下,我想要另一个包含{14, 140, 38}的向量( 7+5+2, 20+80+40, 15+12+11 )。

But I'm struggling to access the values of the objects map.但我正在努力访问objects map 的值。

map<string, vector<int>> objects {/*...*/}

vector<vector<int>> population;

void initializePopulation() {/*...*/}

void getScore(vector<int> individual, vector<int>& sum)
{
    for(int i = 0; i < 3; i++)
    {
        sum.push_back(0);
        for(int j = 0; j < 5; j++)
        {
            if(individual[j] == 1)
            {
                sum[i] += ???;
            }
        }
    }

int main()
{
   /*...*/
   initializePopulation();
   vector<int> sum;
   getScore(population[2], sum);

}

So, as you can see, I'm not sure how to proceed with sum[i] .因此,如您所见,我不确定如何继续sum[i] Any suggestions?有什么建议么? I'm not very fluent in C++, so a more detailed answer would be appreciated!我对 C++ 不是很流利,所以更详细的答案将不胜感激!

For both vector of vectors as well as a map, you can use for each loop!对于向量的向量以及 map,您可以使用每个循环! When your map is filled with value当您的 map 充满值时

for(auto x: objects){
    cout<<x.first<<" "<<x.second<<endl;
}

This will print key-value pairs in a map with space in between!这将在 map 中打印键值对,中间有空格!

In this problem you'll have to iterate values (ie the second) in map too!在这个问题中,您也必须在 map 中迭代值(即第二个)!

{"Object 1", {7, 20, 15}}
{"Object 2", {3, 50, 10}}
{"Object 3", {5, 80, 12}}
{"Object 4", {4, 80, 8}}}
{"Object 5", {2, 40, 11}}

For something like this the following code should work:对于这样的事情,以下代码应该可以工作:

for(auto x: objects){
    cout<<x.first<<" ";
    for(auto y: x.second){
        cout<<y<<" ";
    }
    cout<<endl;
}

For vector of vectors, you can use the same concept!对于向量的向量,您可以使用相同的概念!

Try renaming Object 1, Object 2, .... to just 1,2, .... This will allow you to access values in map by using j from your for loop!尝试将Object 1, Object 2, ....重命名为1,2, ....这将允许您使用 for 循环中的 j 访问 map 中的值!

For a more simplified version consider this prototype instead, since you are using words like population and genetic, I assume your data to be humungous, so you are better off using const reference while passing data around (const&, they won't be copied and will become read-only).对于更简化的版本,请考虑使用此原型,因为您使用诸如人口和遗传之类的词,我假设您的数据非常庞大,因此您最好在传递数据时使用const 引用(const&,它们不会被复制和将变为只读)。 global variable is a bad idea in general.全局变量通常是一个坏主意。

void getScore(map<string, vector<int>> const& objects, vector<int> const& individual, vector<int>& sum)
{
    // iterate over each object for the individual
    for(int i = 0; i < 5; i++)
    {
            // are you sure you want sum as {14, 140, 38} (7+5+2, 20+80+40, 15+12+11) 
            // not {14,0, 140,0, 38} (7+5+2, 0, 20+80+40, 0, 15+12+11)
            // use else part for later
            if(individual[i] == 1)
            {
                // compute sum for each object
                // retrieve object vector
                auto it = objects.find("KEY"); // KEY generation discussed later
                if(it!=objects.end()){ // validate key :::: important
                  vector<int> ob = objects["KEY"];      //it->second
                  sum.push_back(std::accumulate(ob.begin(),ob.end(),0) ); //  https://www.cplusplus.com/reference/numeric/accumulate/
                }
            } /*else {
                sum.push_back(0);
            }*/
        }
    }

KEY generation:密钥生成:

1). 1)。 generating "Object 1":生成“对象 1”:

string key = "Object " + to_string(i+1)
auto it = objects.find(key);

2). 2)。 suggested: use integers as key or go with an enum like建议:使用整数作为键或 go 与枚举类似

enum ObjList{
    OBJECT_1,
    OBJECT_2,
    OBJECT_3
}
auto it = objects.find(i); //mind your indexes

hope it helps, happy coding XD希望它有帮助,快乐编码XD

I think that with some little linear algebra your problem has an easy solution: indeed, if you store the numerical data related to your objects into a matrix A, then for each population vector p your desired result is simply p^TA (or equivalently, A^T p ) where ^T denotes the transpose of a matrix or of a vector.我认为通过一些小的线性代数,您的问题有一个简单的解决方案:确实,如果您将与对象相关的数值数据存储到矩阵 A 中,那么对于每个population向量p ,您想要的结果只是p^TA (或等效地, A^T p ) 其中^T表示矩阵或向量的转置

If you are not planning to employ any linear algebra library, you could implement the scalar product by yourself.如果您不打算使用任何线性代数库,您可以自己实现标量积 Down below there is the code implementing the above idea.下面是实现上述想法的代码。

#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <numeric>

std::vector<int> SP(std::vector<std::vector<int>> const &M, std::vector<int> const &P){
    
    std::vector<int> sums(3,0);

    // perform p^T * A operation
    for (int j=0;j<3;j++)
        for (int i=0;i<5;i++)
            sums[j] += M[i][j] * P[i];

    return sums;
}
int main(){
    
    std::map<std::string, std::vector<int>> objects {
    {"Object 1", {7, 20, 15}},
    {"Object 2", {3, 50, 10}},
    {"Object 3", {5, 80, 12}},
    {"Object 4", {4, 80, 8}},
    {"Object 5", {2, 40, 11}}
    };

    std::vector<std::vector<int>> population(3);
    population[0] = {0, 0, 1, 1, 0};
    population[1] = {1, 0, 0, 0, 1};
    population[2] = {1, 0, 1, 0, 1};


    std::vector<std::vector<int>> A;
    // Extract the numerical data from the map 
    for (auto const& [key, val] : objects)
        A.push_back(val);

    // vector in which the desired values are stored for the 3rd element of the population 
    std::vector<int> s = SP(A,population[2]);

    // Just for checking
    for (int it=0; it<s.size(); it++)
        std::cout << s[it] << std::endl;
    

    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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