我试图找出从文本文件中读取数字的最佳方法,并将这些数字设置为变量。我遇到了麻烦,因为会有多个文本文件将测试我的代码,它们都有不同的长度和大小。样本测试看起来像这样:
0 (1,3) (3,5)
1 (2,6)
2 (4,2)
3 (1,1) (2,4) (4,6)
4 (0,3) (2,7)
如果第一个数字表示图形上的顶点,则坐标中的第一个数字是它在有向图中所朝向的顶点,第二个数字是边缘的权重。我尝试使用getline并将其放入数组中,但在某些测试用例中可能有100个坐标,我不知道如何指定数组大小。我也无法通过括号和逗号进行解析,并且不确定如何使用文本文件中的正确数字初始化变量。
答案 0 :(得分:0)
当您可以使用std::stringstream
将所有元素与输入分开时,解析不应该是那么困难。实际上,您希望首先删除所有的paranthesis然后将元素放入容器中。
#include <fstream>
#include <vector>
#include <string>
#include <sstream>
#include <algorithm>
#include <cctype>
int main()
{
std::ifstream read("file.txt");
std::vector<std::vector<std::pair<int, int>>> graph;
// read until you reach the end of the file
for (std::string line; std::getline(read, line); ) {
// removing punctuation like paranthesis, commas, etc.
std::replace_if(std::begin(line), std::end(line), [] (char x) { return std::ispunct(x); }, ' ');
// inserting the line into a stream that helps us parse the content
std::stringstream ss(line);
// read the node number
int source, destination, weight;
ss >> source;
// create a new vector for the new node, so you can place all it's destinations / weights in it
graph.insert(std::next(std::begin(graph), source), {{}});
// read the dests / weights until you reach the end of the current line
while (ss >> destination >> weight)
graph[source].emplace_back(destination, weight);
}
read.close();
std::ofstream write("output.txt");
for (const auto node : graph) {
for (const auto [dest, weight] : node)
write << "(" << dest << ", " << weight << ") ";
write << '\n';
}
}
请注意,您需要C ++ 17来编译代码。如果使用较旧的C ++标准,则必须使用基本循环而不是ranged-for loops
并省略auto
。我还使用了一对对矢量,但如果你对节点使用结构/类,那么它会更好,以使代码更具可维护性。
答案 1 :(得分:0)
我会用这样的东西:
#include <string>
#include <sstream>
#include <fstream>
#include <vector>
#include <algorithm>
struct coordinate
{
int vertex;
int weight;
};
struct vertex_set
{
int vertex;
std::vector<coordinate> coordinates;
};
std::istream& operator>>(std::istream &in, coordinate &out)
{
char ch1, ch2, ch3;
if (in >> ch1 >> out.to_vertex >> ch2 >> out.weight >> ch3)
{
if ((ch1 != '(') || (ch2 != ',') || (ch3 != ')'))
in.setstate(std::ios_base::failbit);
}
return in;
}
std::istream& operator>>(std::istream &in, std::vector<coordinate> &out)
{
out.clear();
coordinate coord;
while (in >> coord)
out.push_back(coord);
return in;
}
std::istream& operator>>(std::istream &in, vertex_set &out)
{
return in >> out.vertex >> out.coordinates;
}
std::ifstream f("file.txt");
std::string line;
while (std::getline(f, line))
{
vertex_set vs;
if (std::istringstream(line) >> vs)
{
// use vs.vertex and vs.coordinates as needed...
}
}
答案 2 :(得分:0)
这也有效。
#include<iostream>
#include<sstream>
#include<string>
using namespace std;
int main() {
int vertices[1000][3], qv = 0; //use number more than 1000 if it is required
while (cin) {
int n;
char c;
string s;
getline(cin, s);
istringstream is(s);
is >> n;
is >> c;
while (c == '(') {
vertices[qv][0] = n;
is >> vertices[qv][1];
is >> c; //,
is >> vertices[qv++][2];
is >> c; //)
is >> c; //(
}
}
for (int i = 0; i < qv; i++) //unified view
cout << vertices[i][0] << ' ' << vertices[i][1] << ' ' << vertices[i][2] << endl;
for (int i = 0; i < qv; i++) { //initial view
cout << vertices[i][0];
cout << " (" << vertices[i][1] << "," << vertices[i][2] << ")";
while (i + 1 < qv && vertices[i][0] == vertices[i + 1][0]) {
i++;
cout << " (" << vertices[i][1] << "," << vertices[i][2] << ")";
}
cout << endl;
}
}