Zliczenie wyrazów w pliku bez powtórzeń

0

Witam serdecznie ;)
Otóż nie mogę wpaść na pomysł jak rozwiązać jeden z problemów. Mam np taki plik wejściowy (jego budowa będzie zawsze identyczna):

Aleksandrow Ksawerow 10
Aleksandrow JanowLubelski 20
Zglowiaczka Ksawerow 30
Ksawerow Lodz 40
Lodz Zakopane 50
Lodz JanowLubelski 60
JanowLubelski Lodz 70

Teraz te miasta muszę ponumerować i wstawić do tablicy.
Patrząc na plik widać że Aleksandrow to pierwsze miasto, Ksawerow to drugie, sprawdzamy linijkę niżej i znów jest Aleksandrow, aczkolwiek nie może mieć wartości 3 tylko znów 1.
Efekt końcowy chcę taki:

Nr lini | nr miasta | nr miasta | wartość
1 1 2 10
2 1 3 20
3 4 2 30
itd...

Oczywiście w tablicy nie będę miał napisów

Jakiś pomysł na łatwe i szybkie rozwiązanie tego?
Zastanawiałem się nad wczytaniem wszystkiego do stringa, przechodzenie znak po znaku aż do białego znaku i z wyłączeniem znaków ASCII odpowiadających za cyfry, ale po namyślę stwierdziłem że to raczej bez sensu..
Pozdrawiam ;)

5

Trzymaj w std::unordered_map lub std::map miasto ⟶ id.

3
#include <unordered_map>
#include <iostream>
#include <string>
#include <list>
using namespace std;

struct node;
struct edge
  {
   node &to;
   double weight;
   edge(node &to,double weight):to(to),weight(weight) {}
  };
struct node
  {
   string name;
   list<edge> neighbors;
  };
typedef unordered_map<string,node> graph;
  
node &find(graph &g,const string &name)
  {
   node &ret=g[name];
   ret.name=name;
   return ret;
  }

void append(graph &g,const string &a,const string &b,double weight)
  { 
   node &A=find(g,a),&B=find(g,b);
   A.neighbors.push_back(edge(B,weight));
   B.neighbors.push_back(edge(A,weight)); // jeżeli nieskierowany
  }

int main()
  {
   graph g;
   append(g,"Aleksandrow","Ksawerow",10);
   append(g,"Aleksandrow","JanowLubelski",20);
   append(g,"Zglowiaczka","Ksawerow",30);
   append(g,"Ksawerow","Lodz",40);
   append(g,"Lodz","Zakopane",50);
   append(g,"Lodz","JanowLubelski",60);
   append(g,"JanowLubelski","Lodz",70);
   for(auto &node:g)
     {
      cout<<node.first<<endl;
      for(auto &e:node.second.neighbors) cout<<'\t'<<e.to.name<<" -> "<<e.weight<<endl;
     }
   return 0;
  }

http://ideone.com/uugW2h

6
niemamnicku napisał(a):

Zastanawiałem się nad wczytaniem wszystkiego do stringa, przechodzenie znak po znaku aż do białego znaku i z wyłączeniem znaków ASCII odpowiadających za cyfry, ale po namyślę stwierdziłem że to raczej bez sensu..
Pozdrawiam ;)

Po co?

std::String sLine;
int lineNr = 0;
while (std::getline(inFile, sLine)) {
    ++lineNr;
    std::istringstream rowData(sLinie);
    std::string cityA, cityB;
    int distance;
    if (rowData >> cityA >> cityB >> distance) {
          outFile << lineNr << '\t' << cityCollection.GetCityId(cityA) << '\t'  << cityCollection.GetCityId(cityB) << '\t' << distance << std::end;
    }
}
0

Dziękuje bardzo za odpowiedzi ;)
MarekR22, powiedz mi bardzo proszę czym jest cityCollection, podejrzewam że jakiś zbiór, jak mam to zadeklarować?
Jak na razie się ucze, więc proszę o wyrozumiałość.

/edit/

Nie do końca umiem używać Waszych sposób więc sam kombinuje i na chwile obecną wymyśliłem coś takiego:
Deklaruje

   map<int, string> miasto;
   map<int, string> miasto2; 

tutaj deklaracja fstrem
a następnie

 
 std::string sLine;
int lineNr = 0;
while (std::getline(inFile, sLine)) {
    ++lineNr;
    std::istringstream rowData(sLine);
    std::string cityA, cityB;
    int distance;
    if (rowData >> cityA >> cityB >> distance) {
            miasto[lineNr] = cityA;
            miasto2[lineNr] = cityB;
          //std::cout << lineNr << '\t' << cityCollection.GetCityId(cityA) << '\t'  << cityCollection.GetCityId(cityB) << '\t' << distance ;
          std::cout << cityA << cityB <<distance;
    }
}

:

Mam teraz w dwóch zmiennych miasta:
miasta.png

aczkolwiek nie wiem jak je ponumerować, bez powtórzeń, tak jak pisałem wcześniej.
Teraz tak na to patrze i znów twierdzę że mój pomysł jest do ....

1
niemamnicku napisał(a):

MarekR22, powiedz mi bardzo proszę czym jest cityCollection, podejrzewam że jakiś zbiór, jak mam to zadeklarować?

To powinien być obiekt klasy, który zapewnia logikę gromadzenia nazw miast i przyporządkowania im identyfikatorów. To dostałeś od poprzedników.
Masz komplet podpowiedzi, masz tylko poskładać wszystko do kupy.
Nie mam zamiaru dawać gotowca.

0

Dziękuje bardzo, udało mi się zrobić, wszystko działa jak należy ;)

Pozdrawiam!

1 użytkowników online, w tym zalogowanych: 0, gości: 1