簡體   English   中英

我如何將這個文件讀入地圖C ++

[英]How would i read this file into a map c++

我正在努力弄清楚如何將此文件讀入地圖。 我首先將文件讀入向量。 然后嘗試獲取向量中的字符串值並將其插入到映射中。 我完全迷路了。

第一個值是鍵,有序對是值。 我需要添加“無限數量的值”

1 2,1 8,2
2 1,1 3,1
3 2,1 4,1
4 3,1 5,1
5 4,1 6,1
6 5,1 7,1
7 6,1 8,1
8 7,1 1,2

當前閱讀代碼:

int main(int argc, char const *argv[]){

     map<int, string> map;
     vector<string> v;
     vector<int>    v2;
     string line;
     string fileName(argv[1]);
     ifstream inputFile;
     inputFile.open(fileName);

     while(getline(inputFile, line)){
         v.push_back(line);
     }

    return 0;
}

您指定每行的初始值是一個連續鍵,每行的其余值由空格分隔的元組組成,每個元組是兩個用逗號分隔的值,第一個值是其他一些標識符,並且因此,同一行上所有元組的第一個值將是唯一的。

因此,我建議使用以下數據結構:

typedef std::vector<std::map<int, int>> map_t;

向量索引將是初始關鍵字。 向量索引從0開始,在數據文件中從1開始,但這很容易處理。 要么更改您的數據文件,要么繼續使用沒有數據的鍵0。

向量中的每個值都是一個映射。 地圖的鍵是“另一個節點” ID,值是到另一個節點的距離-根據您對該數據含義的描述。

該數據結構將很好地對該數據建模。 現在,就讀取和解析此數據而言:

您最初的方法是正確的:使用std::getline()將每一行讀入一個字符串:

map_t my_map;

std::string line;

while (std::getline(inputFile, line)) {

    // Here be dragons

}

首先,將每一line放入字符串向量中沒有任何收獲。 我們可以在閱讀時簡單地解析每一行。 在循環內部,我們將處理讀取的每一行,並將其數據直接放入my_map 那是計划。 簡單,容易和直接。

在循環內部,我們首先將每一行放入std::istringstream中以對其進行解析,然后提取初始節點ID:

int node_id;

std::istringstream line_stream(line);

line_stream >> node_id;

很簡單。 如果需要處理錯誤的輸入,則應該能夠自己在此處以及其余代碼中找出如何檢查轉換失敗的方法。

現在,我們只需要拔出每個“ other_node,distance”元組對:

std::string node_distance;
std::map<int, int> node_distance_map;

while (line_stream >> node_distance)
{
     // Here be more dragons.
}

就是這樣。 在有更多龍的循環內部, node_distance將是每個單獨的“ n,n”字符串,具有兩個值。 這很簡單,您可以自己弄清楚:如何自己從字符串中提取這兩個整數; 然后更新node_distance_map 然后,在此while_loop您將構造的node_id提取node_distance_map ,並將node_id提取,然后將整個內容填充到my_map 任務完成。 這似乎並不困難,不是嗎?

檢查此解決方案,它不是最佳解決方案,但可以實現目標:

map<int, vector<pair<int, int>>> result;

ifstream infile("C:\\Users\\Mohamed\\Desktop\\test.txt");

string line;
while (getline(infile, line)) {

    istringstream iss(line);
    vector<string> tokens{istream_iterator<string>{iss},
                          istream_iterator<string>{}};

    if(tokens.size() == 0) continue; // Workaround

    int pair1FirstValue, pair1SecondValue, pair2FirstValue, pair2SecondValue;

    string pair1 = tokens.at(1);
    string pair2 = tokens.at(2);

    sscanf(pair1.c_str(), "%d,%d", &pair1FirstValue, &pair1SecondValue);
    sscanf(pair2.c_str(), "%d,%d", &pair2FirstValue, &pair2SecondValue);

    vector<pair<int,int>> valueVector { make_pair(pair1FirstValue, pair1SecondValue), make_pair(pair2FirstValue, pair2SecondValue) };

    result.insert(make_pair(stoi(tokens.at(0)), valueVector));
}

cout << "Printing the map: " << endl;

for(auto it = result.begin(); it != result.end(); it++) {

    cout << it->first << " "
         << it->second.at(0).first << " " << it->second.at(0).second << " "
         << it->second.at(1).first << " " << it->second.at(1).second << endl;
}

為了構建代碼,您需要包括以下頭文件:

#include <iostream>
#include <sstream>
#include <fstream>

嘗試理解代碼,並解決變通辦法,祝您好運。

這是一個簡單的閱讀示例。 絕不是最佳選擇,但它應該易於閱讀,理解,調試和啟動OP。 如果讀取文件是處理時間的重要因素,請考慮使用狀態機之類的東西。

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

int main(int argc, char const *argv[])
{

    std::vector<std::map<int, int>>adjacencies;
    std::string line;

    if (argc >=2 ) // no argv[1] if argc < 2
    {
        std::ifstream inputFile(argv[1]);

        while(getline(inputFile, line)) // get a line until no more lines
        {
            std::map<int,int> temp; // holder for adjacent nodes as we find them
            std::stringstream ss(line); // stream to ease parsing of nodes from line
            std::string node;
            while (ss >> node) // get adjacent node on this line until end of line
            {
                std::stringstream ss2(node); //stream to ease taking nodes apart
                int key;
                char comma;
                int weight;
                if (ss2 >> key >> comma >> weight) // take apart node
                {
                    temp[key] = weight; // put adjacent node in list
                }
                else
                {
                    std::cerr << "File is bogus. Bailing\n";
                    return -1;
                }
            }

            adjacencies.push_back(temp); // put node and all adjacencies in list
        }

        try
        {
            auto weight_of_15_8 = adjacencies[15-1].at(8);
            //-1 because origin 0 indexing
        }
        catch(std::out_of_range &)
        {
            std::cerr << "node 15 is not adjacent to 8\n";
        }

        return 0;
    }
    else
    {
        std::cerr << "Usage <prog name here> <filename here>\n";
        return -2;
    }
}

這個異常特別慢,但是如果在map沒有鍵,則使用[] map將創建並默認初始化該值。 您不希望列表中包含鄰接的零節點,因此最好盡早解決該錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM