【问题标题】:How to insert vector of integers into Key, Value of std::map如何将整数向量插入键,std :: map的值
【发布时间】:2018-08-26 22:58:50
【问题描述】:

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

认为这很容易,但我很惊讶我已经在 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;
}

【问题讨论】:

  • 听起来您的代码无法编译。发布您在编译时遇到问题的一行代码,而不是整个程序。
  • 如果你的编译器没有告诉你错误发生在哪一行,把它扔掉,找一个能告诉你的。但是考虑到 Xcode 是一个被很多人使用的严肃工具,我很难相信它会给你一个没有行引用的错误。
  • 如果您不知道如何使用 IDE 告诉您行号,请尝试注释掉不同的部分,直到您弄明白为止。
  • @user3152377 究竟是什么,key(const std::pair&lt;std::string, std::string&gt;&amp; keyValue)value(const std::pair&lt;std::string, std::string&gt;&amp; keyValue) 在您的std::transform 中?以及为什么程序无法打开文件;你会不考虑就关闭的,对吧?
  • @user3152377 如果您的评论以 it is reading as... 开头是您的编译错误消息,那么请编辑您的原始帖子以添加该文本。这将使您的读者不必通过所有的 cmets 来查找该信息。我对 Xcode 不熟悉,但我猜 2031 是您的行号,而 26 是您在文件 algorithm 中的列号。

标签: c++ key-value ifstream stdvector stdmap


【解决方案1】:

您可以直接引用 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】:

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


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

如果是这样,

1。从从文件中读取整数开始,您就遇到了问题。 在那里,您无缘无故地使用double 并存储到 std::vector&lt;int&gt;(即print1print2)。


2。其次,如果您的文件尚未打开怎么办? 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
}

3。如果您的意图是只打印 keysvalues,则不需要 需要将它们解析为不同的向量。 你可以直接做:

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。如果您真的想将它们解析为不同的向量;首先,存储keys的数据结构不对:

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

它应该是整数向量的向量,就像你的vType = std::vector&lt;int&gt;。也就是说,

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

其次,您的函数 key(const std::pair&lt;std::string, std::string&gt;&amp; keyValue)value(const std::pair&lt;std::string, std::string&gt;&amp; 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

【讨论】:

  • 我非常感谢在线编译器的建议和指向我的代码失败的地方并且可以提高效率的指针。感谢您推进我的 C++ 知识。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-08-19
  • 1970-01-01
  • 1970-01-01
  • 2020-03-10
  • 1970-01-01
  • 2012-09-20
  • 1970-01-01
相关资源
最近更新 更多