简体   繁体   English

如何将整数向量插入到Key,std :: map的值中

[英]How to insert vector of integers into Key, Value of std::map

Goal: Read numerical text files into vectors and then add the vectors to key,value std::map so that I can reference them by the key name I have specified for them, later. 目标:将数字文本文件读入向量,然后将向量添加到键,值std::map以便我可以通过我为其指定的键名称引用它们。

Thought this would be easy and I am surprised that I can't find an answer for this already on StackOverflow. 认为这很容易,我很惊讶我在StackOverflow上找不到这个答案。

Result Expected : 结果预期

Print1 = {100,200,500,600}

Print2 = {7890,5678,34567,3,56}

Print3["NameA"] = Print1

Print3["NameB"] = Print2

If my process is inefficient or going in the wrong direction, I would appreciate the pointers. 如果我的过程效率低下或方向错误,我会很感激。

I keep getting Semantic Issue build fails and no viable conversion from pair <const basic_string> 我一直在使用语义问题构建失败,并且没有来自pair <const basic_string>可行转换

Current Code: 现行代码:

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

const std::string& key(const std::pair<std::string, std::string>& keyValue)
{
    return keyValue.first;
}

const std::string& value(const std::pair<std::string, std::string>& keyValue)
{
    return keyValue.second;
}

int main() 
{
    std::vector<int> print1;
    std::ifstream inputFile("numbers.txt");

    // test file open
    if (inputFile) 
    {
        double value; 
        // read the elements in the file into a vector
        while ( inputFile >> value ) {
            print1.push_back(value);
        }
    }
    inputFile.close();

    std::vector<int> print2;
    std::ifstream inputFile2("numbers2.txt");

    // test file open
    if (inputFile2) 
    {
        double value;              
        // read the elements in the file into a vector
        while ( inputFile2 >> value ) {
            print2.push_back(value);
        }
    }       
    inputFile2.close();

    std::map<std::string, std::vector<int>> contacts;   
    contacts["alice"] = print1;
    contacts["bob"] = print2;

    std::vector<std::string> keys(contacts.size());
    std::vector<int> values(contacts.size());

    transform(contacts.begin(), contacts.end(), keys.begin(), key);
    transform(contacts.begin(), contacts.end(), values.begin(), value);

    std::cout << "Keys:\n";
    copy(keys.begin(), keys.end(), std::ostream_iterator<std::string>(std::cout, "\n"));

    std::cout << "\n";

    std::cout << "Values:\n";
    copy(values.begin(), values.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
    return 0;
}

First of all, there is no point in arguing that Xcode didn't show any error msgs for your code. 首先,没有必要争论Xcode没有为您的代码显示任何错误信息。 Try either turning on all the compiler warnings or try in online compilers. 尝试打开所有编译器警告或尝试在线编译器。 The result will be not disappointing: https://godbolt.org/z/cU54GX 结果将不会令人失望: https//godbolt.org/z/cU54GX


If I have understood correctly, you want to store your information from two files(the integer values) in a std::map , where its key = std::string and value = vector of integer array . 如果我理解正确,您希望将信息存储在std::map中的两个文件(整数值)中,其中key = std::string ,value = vector of integer array

If so, 如果是这样的话,

1 . 1 You have your problem starting from reading integers from files. 从文件中读取整数开始就有问题了。 There you are using double for no reason and storing to std::vector<int> (i,e print1 and print2 ). 在那里你无缘无故地使用double并存储到std::vector<int> (i,e print1print2 )。


2 . 2 Secondly, what if your file has not been open?. 其次,如果您的文件尚未打开怎么办? inputFile.close(); and inputFile2.close(); inputFile2.close(); will close it anyway, without knowing the fact. 无论如何都会关闭它,却不知道这个事实。 This is wrong. 这是错的。 The proper way would be: 正确的方法是:

inputFile.open("numbers.txt", std::ios::in); // opening mode
if (inputFile.is_open()) { 
   // do stuff
   inputFile.close(); // you need closing only when file has been opened
}

3 . 3 If your intention is to only print keys and values , you don't need to parse them to different vectors. 如果您的目的是仅打印keysvalues ,则无需将它们解析为不同的向量。 You can do it directly: 你可以直接做到:

for(const std::pair<kType, vType>& mapEntry: contacts)
{
    std::cout << "Key: " << mapEntry.first << "   Values: ";
    for(const int values: mapEntry.second) std::cout << values << " ";
    std::cout << std::endl;
}

In c++17 you can use Structured binding 在c ++ 17中,您可以使用结构化绑定

for(const auto& [Key, Values]: contacts)
{
    std::cout << "Key: " << Key << "   Values: ";
    for(const int value: Values) std::cout << value << " ";
    std::cout << std::endl;
}

4 . 4 If you really want to parse them to a different vector; 如果你真的想要将它们解析为另一个向量; first of all, the data structure for storing keys is wrong: 首先,存储keys的数据结构是错误的:

std::vector<int> values(contacts.size());
          ^^^^^^

which should have been a vector of vector of integers, as your vType = std::vector<int> . 它应该是整数向量的向量,如你的vType = std::vector<int> That is, 那是,

std::vector<std::vector<int>> values
           ^^^^^^^^^^^^^^^^^^

Secondly, you have the functions key(const std::pair<std::string, std::string>& keyValue) and value(const std::pair<std::string, std::string>& keyValue) wrong, where you are passing a pair of strings as keys and values. 其次,你有函数key(const std::pair<std::string, std::string>& keyValue)value(const std::pair<std::string, std::string>& keyValue)错误,您将一对字符串作为键和值传递。

This should have been 这应该是

typedef std::string    kType;  // type of your map's key
typedef std::vector<int> vType;// value of your map's value
std::pair<kType, vType>

However, you can simply replace with lambdas, which would be more intuitive, in the sense of having the functions next to the line where you needed. 但是,您可以简单地替换为lambdas,这将更直观,在您需要的行旁边具有功能。 For example, 例如,

std::vector<kType> keysVec; 
keysVec.reserve(contacts.size());
auto getOnlyKeys   = [](const std::pair<kType, vType>& mapEntry){  return mapEntry.first; };
std::transform(contacts.begin(), contacts.end(), std::back_inserter(keysVec), getOnlyKeys);

See an example code here 请在此处查看示例代码

You can reference map element directly which will create an entry if doesn't exist, and just fill it from the file read loop: 您可以直接引用map元素,如果不存在则会创建一个条目,只需从文件读取循环中填充它:

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


int main()
{
    std::map<std::string, std::vector<int>> m;
    int num;

    auto &&alice = m["alice"];
    std::ifstream if_alice("numbers1.txt");

    while (if_alice >> num)
        alice.push_back(num);

    if_alice.close();

    auto &&bob = m["bob"];
    std::ifstream if_bob("numbers2.txt");

    while (if_bob >> num)
        bob.push_back(num);

    if_bob.close();

    // test
    for (auto &&data : m)
    {
        std::cout << "Name: " << data.first << "\t";
        for (int num : data.second)
            std::cout << num << " ";
        std::cout << "\n";
    }
}

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

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