3 votes

Comment insérer un vecteur d'entiers dans Key, Value de std::map

Objectif : Lire des fichiers texte numériques en vecteurs et ajouter les vecteurs à la clé, à la valeur. std::map afin de pouvoir les référencer ultérieurement par le nom de clé que j'ai spécifié.

Je pensais que ce serait facile et je suis surpris de ne pas trouver de réponse sur StackOverflow.

Résultat attendu :

Print1 = {100,200,500,600}

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

Print3["NameA"] = Print1

Print3["NameB"] = Print2

Si mon processus est inefficace ou s'il va dans la mauvaise direction, je vous serais reconnaissant de me donner des conseils.

Je n'arrête pas d'obtenir des échecs de construction de Semantic Issue et aucune conversion viable de pair <const basic_string>

Code actuel :

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

1voto

JeJo Points 12135

Tout d'abord, il est inutile d'affirmer que Xcode n'a pas affiché de message d'erreur pour votre code. Essayez d'activer tous les avertissements du compilateur ou essayez les compilateurs en ligne. Le résultat ne sera pas décevant : https://godbolt.org/z/cU54GX


Si j'ai bien compris, vous voulez stocker vos informations provenant de deux fichiers (les valeurs entières) dans un fichier std::map où sa clé = std::string et valeur = vector of integer array .

Si c'est le cas,

1 . Vous avez votre problème en commençant par lire Vous utilisez alors double sans raison et de la stor std::vector<int> (i,e print1 y print2 ).


2 . Deuxièmement, que se passe-t-il si votre dossier n'a pas été ouvert ? inputFile.close(); et inputFile2.close(); le fermera de toute façon, sans connaître le fait. C'est une erreur. La bonne méthode serait la suivante :

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 . Si votre intention est de n'imprimer que des keys y values , de les analyser en différents vecteurs. Vous pouvez le faire directement :

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

En c++17, vous pouvez utiliser Liaison structurée

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

4 . Si vous voulez vraiment les analyser dans un vecteur différent, il faut tout d'abord que la structure de données pour le stockage de keys est erronée :

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

qui aurait dû être un vecteur de vecteurs d'entiers, comme votre vType = std::vector<int> . C'est-à-dire,

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

Deuxièmement, vous disposez des fonctions key(const std::pair<std::string, std::string>& keyValue) y value(const std::pair<std::string, std::string>& keyValue) erronée, où vous passez un paire de chaînes comme clés et valeurs.

Cela aurait dû être

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>

Cependant, vous pouvez simplement les remplacer par des lambdas, ce qui serait plus intuitif, dans le sens où les fonctions se trouveraient à côté de la ligne où vous en avez besoin. Par exemple,

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

<strong><a href="https://wandbox.org/permlink/HVkzPqAf6BOxdBsD" rel="nofollow noreferrer">See an example code here</a></strong>

1voto

Killzone Kid Points 4918

Vous pouvez faire référence à l'élément map directement, ce qui créera une entrée si elle n'existe pas, et la remplir à partir de la boucle de lecture du fichier :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X