合并文本文件不同行中的重复项

Merging duplicates in different lines of a text file

本文关键字:文本 文件 合并      更新时间:2023-10-16

我有一个文本文件,其中行上的第一个数字是图形的节点号,第二个数字是连接到第一个节点的节点号。第三个数字是边缘的重量。

下面是一个示例案例,其中文件中的两行包含权重为 .5 的 3 和 5:

1 3 0.5
3 5 0.5
3 6 0.5
3 5 0.5
6 8 0.5
4 6 1

我希望能够将它们合并到一行中,该行具有 3 和 5 的连接,但将权重更新为它们的权重之和(在本例中为 1(。然后应删除重复的行。

所以我想检查重复的节点对,如果我发现重复的节点对,请汇总所有节点的总权重,然后更新该对的一行以获得正确的总权重,然后删除具有这些节点的所有其他行。

我已经为边缘做了一个结构:

struct Edge {
int c1, c2;
float weight;
};

我已经阅读了文件并将它们全部放入此结构中:

if (updateGraph.is_open()) {
string data[3];
Edge e;
while (getline(updateGraph, stri)) {
stringstream in(stri);
int i = 0;
while (in.good() && i < 3) {
in >> data[i];
i++;
}
e.c1 = atoi(data[0].c_str());
e.c2 = atoi(data[1].c_str());
e.weight = atof(data[2].c_str());
cout << e.c1 << " " << e.c2 << " " << e.weight << endl;
}
}

但是现在我不确定如何比较它们以查看是否有任何边缘具有相同的 c1 和 c2。 我该怎么做?

我已经阅读了文件并将它们全部放入此结构中:[...]但是现在我不确定如何比较它们以查看是否有任何边缘具有相同的 c1 和 c2。

从逻辑上讲,您知道您需要做的不仅仅是阅读边缘并打印出来。 你的程序必须保留一些到目前为止它看到的边缘的记忆。 例如,它可能必须将第一行的边与最后一行合并。

我该怎么做?

没有单一的"正确"方法可以做到这一点。 但是,如果您尝试创建自己的类,就像您定义的Edge结构一样,那么您将不得不编写更多代码。 例如,要使用 std::set 集合,您需要一个比较运算符。(请注意,C++甚至不提供默认的相等运算符。

如果您避免创建自定义结构,C++可以为您做更多工作。 相反,您可以将状态存储为从std::tuple<int, int>到浮点权重的 std::map。 元组已经知道如何相互比较。 这种思维方式将边缘的概念与重量的概念分开。

无需为您编写代码,这里演示了您正在寻找的功能类型......以"常规"C++方式完成:

#include <iostream>
#include <map>
#include <tuple>
typedef std::tuple<int, int> Edge;
std::map<Edge, float> mapEdgeToWeight;
int main() {
Edge e1 {3, 5}; float w1 = 0.5;
Edge e2 {3, 5}; float w2 = 0.5;
auto it1 = mapEdgeToWeight.find(e1);
if (it1 != mapEdgeToWeight.end())
std::cout << "Existing {3, 5} edge (won't happen)n";
else {
std::cout << "First {3, 5} edge (this is first)n";
mapEdgeToWeight[e1] = w1;
}
auto it2 = mapEdgeToWeight.find(e2);
if (it2 != mapEdgeToWeight.end()) {
std::cout << "Existing {3, 5} edge (now happens)n";
it2->second += w2; // first is edge, second is weight
}
else
std::cout << "First {3, 5} edge (it isn't first!)n";
for (auto &pair : mapEdgeToWeight)
std::cout << "Edge: "
<< std::get<0>(pair.first) << ","
<< std::get<1>(pair.first)
<< " Weight: " << pair.second << "n";
}

正如评论中所建议的那样,您最好考虑在...正在处理它...然后写出一个新文件,而不是考虑在现有文件中"合并行"。

如果你是C++新手,那么有很多东西需要学习,而来到StackOverflow时不知道如何写东西并问"我会怎么做?"肯定是一个艰难的方法。 我建议通过阅读一本关于这个主题的书来打下坚实的基础。 即使您正在上一门带有自己文本的课程,也不要害怕通过在这里选择一个好的现代课程来猜测它:

权威C++书指南和清单

但是现在您至少知道一个地方可以从一个地方开始,通过查看有关如何使用 std::map 和 std::tuple 的教程。