代码之家  ›  专栏  ›  技术社区  ›  user3152377

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

  •  3
  • user3152377  · 技术社区  · 7 年前

    目标: 将数字文本文件读入向量,然后将向量添加到key,value std::map 以便以后可以按为它们指定的密钥名引用它们。

    我以为这很简单,但我很惊讶,我在StackOverflow上找不到答案。

    预期结果 :

    Print1 = {100,200,500,600}
    
    Print2 = {7890,5678,34567,3,56}
    
    Print3["NameA"] = Print1
    
    Print3["NameB"] = Print2
    

    如果我的流程效率低下或走错了方向,我会感谢你的指点。

    我总是得到语义问题构建失败,没有可行的转换 pair <const basic_string>

    当前代码:

    #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;
    }
    
    2 回复  |  直到 7 年前
        1
  •  1
  •   Killzone Kid    7 年前

    您可以直接引用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";
        }
    }
    
        2
  •  1
  •   JeJo    7 年前

    首先,争论Xcode没有为您的代码显示任何错误消息是没有意义的。请尝试打开所有编译器警告或尝试联机编译器。结果不会令人失望: https://godbolt.org/z/cU54GX


    如果我理解正确,您需要将来自两个文件(整数值)的信息存储在 std::map ,其中的键= std::string 和价值= vector of integer array .

    如果是的话,

    1个 . 从文件中读取整数时出现问题。 你用的是 double 无故存放 std::vector<int> (即 print1 print2 ).


    . 其次,如果你的文件还没有打开呢?。 inputFile.close(); inputFile2.close(); 无论如何都会关闭它,而不知道 事实。这是错误的。 正确的方法是:

    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
    }
    

    . 如果你只想打印 keys values ,你没有 需要将它们解析为不同的向量。 你可以直接做:

    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;
    }
    

    在c++17中,您可以使用 Structured binding

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

    4个 . 如果您真的想将它们解析为一个不同的向量;首先,要存储的数据结构 钥匙 是错误的:

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

    它应该是整数向量的向量,就像 vType = std::vector<int> . 也就是说,

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

    其次,你有 key(const std::pair<std::string, std::string>& keyValue) value(const std::pair<std::string, std::string>& keyValue) 错了,你经过的地方 一对线 作为键和值。

    这应该是

    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>
    

    但是,您可以简单地替换为lambdas,这将更直观,因为在需要的行旁边有函数。例如,

    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