我将如何读取这个文件到一个映射c++
How would i read this file into a map c++
我正在努力弄清楚如何将此文件读取为地图。我先把文件读入一个矢量。然后试图取向量中的字符串值并将它插入到map中。我完全迷路了。
第一个值是键,有序对是值。我需要添加"infinite number of values"
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。
vector中的每个值都是一个map。映射的键是"other node"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"字符串,有两个值。这很简单,你们自己就能弄明白如何从这个字符串中提取这两个int;然后更新node_distance_map
。然后,在此while_loop
之后,您使用构建的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. Bailingn";
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 8n";
}
return 0;
}
else
{
std::cerr << "Usage <prog name here> <filename here>n";
return -2;
}
}
这个异常特别慢,但是如果一个键不在map
中,如果你使用[]
, map
将创建并默认初始化这个值。你不会想要一个满是邻接零节点的列表,所以最好早点消除这个bug。
- 为什么在 std::map 上移动无法将元素从一个映射移动到另一个映射
- C++在一个映射中存储不同的指针类型(并处理销毁)
- 将一个向量对放在一个无序映射与一个映射中
- 我正在尝试创建一个C++映射,该映射在boost内存映射文件中具有向量值
- 如何将键和值从映射传输到另一个映射?
- 在插入时同时迭代一个映射,这在什么方面是不安全的
- 如何制作一个C++映射容器,其中键是值的一部分
- 将一个映射插入到同一多重映射的另一个映射中会导致 SEG 错误
- 在一个映射向量上迭代,如果满足条件,则插入一个副本
- 如何将键值对引用从一个映射复制到同一类型的另一个映射
- 在C++中,如何创建一个映射,其值是protobuf扩展标识符
- C++:使用映射作为另一个映射的值
- 我可以有一个C++映射,其中多个键引用该值而不使用指针吗
- 我想开发一个函数,它接受任何类型的向量并返回一个映射(类似于 python 中的计数器)
- 如何用一对向量输出一个映射
- 如何在c++中根据另一个映射对一个映射进行排序
- 我将如何读取这个文件到一个映射c++
- 我们可以在c++中制作一个映射,将值作为键的函数
- 用map-values初始化一个映射
- 在c++中返回一个映射,用作lua中的表