Как вставить вектор целых чисел в ключ, значение std :: map

Цель: Считайте числовые текстовые файлы в векторы, а затем добавьте векторы в ключ, значение std::map, чтобы я мог ссылаться на них по имени ключа, которое я указал для них позже.

Думал, что это будет легко, и я удивлен, что не могу найти ответ на это уже в StackOverflow.

Ожидаемый результат:

Print1 = {100,200,500,600}

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

Print3["NameA"] = Print1

Print3["NameB"] = Print2

Если мой процесс неэффективен или идет в неправильном направлении, я был бы признателен за указатели.

Я продолжаю получать ошибки сборки Semantic Issue, и нет жизнеспособного преобразования из 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;
}

Похоже, ваш код не компилируется. Опубликуйте одну строку кода, при компиляции которой у вас возникли проблемы, а не всю программу.

John Zwinck 26.08.2018 06:19

Если ваш компилятор не сообщает вам, в какой строке возникает ошибка, выбросьте ее и получите ту, которая сообщает. Но учитывая, что Xcode - серьезный инструмент, которым пользуется множество людей, мне трудно поверить, что он выдает ошибку без ссылки на строку.

John Zwinck 26.08.2018 06:25

Если вы не можете понять, как использовать вашу среду IDE, чтобы сообщить вам номер строки, просто попробуйте закомментировать разные части, пока не разберетесь.

John Zwinck 26.08.2018 06:32

Вы прошли? Не получается? Я думал, ты не сможешь скомпилировать. Как можно выполнить программу, которая не компилируется? И как он мог не скомпилироваться на такой тривиальной строчке, как создание карты?

John Zwinck 26.08.2018 06:41

@ user3152377 что именно, key(const std::pair<std::string, std::string>& keyValue) и value(const std::pair<std::string, std::string>& keyValue) в вашем std::transform? И почему, если программа не смогла открыть файл; вы закроете, не считаясь с этим, не так ли?

JeJo 26.08.2018 08:51

@ user3152377, если ваш комментарий, начинающийся с это читается как ..., является сообщением об ошибке компиляции, отредактируйте исходное сообщение, чтобы добавить этот текст. Это избавит ваших читателей от необходимости рыться во всех комментариях, чтобы найти нужную информацию. Я не знаком с Xcode, но предполагаю, что 2031 г. - это номер вашей строки, а 26 - номер вашего столбца в файле алгоритм.

Frank Boyne 26.08.2018 08:52
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
6
2 042
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Прежде всего, нет смысла утверждать, что Xcode не показывал никаких сообщений об ошибках для вашего кода. Попробуйте либо включить все предупреждения компилятора, либо попробуйте онлайн-компиляторы. Результат не разочарует: https://godbolt.org/z/cU54GX


Если я правильно понял, вы хотите сохранить свою информацию из двух файлов (целочисленные значения) в std::map, где его ключ = std::string и значение = vector of integer array.

Если так,

1. У вас проблема, начиная с чтения целых чисел из файлов. Здесь вы используете double без причины и сохраняете его в std::vector<int> (т.е. print1 и print2).


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. Если вы намерены печатать только 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;
}

В С ++ 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. Если вы действительно хотите разобрать их на другой вектор; во-первых, неправильная структура данных для хранения keys:

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>

Однако вы можете просто заменить лямбда-выражения, что будет более интуитивно понятным в том смысле, что функции будут располагаться рядом с нужной строкой. Например,

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++.

user3152377 26.08.2018 19:32
Ответ принят как подходящий

Вы можете напрямую ссылаться на элемент карты, который создаст запись, если она не существует, и просто заполните ее из цикла чтения файла:

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

Красиво и оперативно! Спасибо.

user3152377 26.08.2018 19:22

Другие вопросы по теме