Слияние дубликатов в разных строках текстового файла - PullRequest
0 голосов
/ 16 октября 2018

У меня есть текстовый файл, где первое число в строке - это номер узла для графа, а второе число - это номер узла, который подключен к первому.Третье число - это вес ребра.

Вот пример случая, когда две строки в файле содержат 3 и 5 с весом .5:

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

Iхотел бы иметь возможность объединить их в одну строку, которая имеет соединение для 3 и 5, но обновлять вес, чтобы он был суммой их весов (в данном случае 1).Дублирующая строка затем должна быть удалена.

Поэтому я хочу проверить наличие дублирующих пар узлов, и, если я найду дубликаты, суммировать общий вес всех их, а затем обновить одну строку для этой пары, чтобы получить правильнуюобщий вес, а затем удалите все остальные строки с этими узлами.

Я создал структуру для Edges:

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.Как бы я это сделал?

1 Ответ

0 голосов
/ 19 октября 2018

Я прочитал файл и поместил их все в эту структуру: [...] Но теперь я не уверен, как их сравнить, чтобы увидеть, имеют ли какие-либо ребра одинаковые c1 и c2.

Логически говоря, вы знаете, что вам нужно сделать больше, чем просто прочитать края и распечатать их.Ваша программа должна сохранять память о краях, которые она видела до сих пор.Возможно, придется объединить ребро из самой первой строки с самой последней строкой - например.

Как бы я это сделал?

Там нет ни одного "правильный "способ сделать это.Но если вы попытаетесь создать свой собственный класс, подобный структуре Edge, которую вы определили, вам придется писать больше кода.Чтобы использовать коллекцию std :: set , вам понадобится оператор сравнения , например. (Обратите внимание, что C ++ даже не предоставляет оператор равенства по умолчанию .)

C ++ может сделать больше за вас, если вы избежите создания пользовательской структуры.Вместо этого вы можете сохранить свое состояние как std :: map от std::tuple<int, int> до значения с плавающей запятой.Кортежи уже будут знать, как сравнивать друг с другом.Этот способ мышления отделяет идею о крае от идеи о весе.

Без написания своего кода для вас, вот демонстрация того типа способностей, которые вы ищете ... сделали «обычные»C ++ way:

#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, не зная, как что-то написать, и спрашиваете" как бы я это сделал? "определенно будет скалистый подход.Я бы посоветовал получить прочную основу, пролистав книгу на эту тему.Даже если вы посещаете урок с собственным текстом, не бойтесь угадать его, выбрав здесь хороший современный:

The Definitive C ++ Book Guide и List

Но теперь вы знаете по крайней мере одно место, которое вы можете начать, изучая руководства по использованию std :: map и std :: tuple.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...