View difference between Paste ID: gi1vkcBb and 90utvKDK
SHOW: | | - or go back to the newest paste.
1
-----------------------------------------------------------------------
2
main.cpp
3
-----------------------------------------------------------------------
4
#include "transport_catalogue.h"
5
#include "input_reader.h"
6
#include "stat_reader.h"
7
8
using namespace std;
9
10
int main() {
11
    TransportCatalogue catalogue;
12
    input_(catalogue);
13
    output_(catalogue);  
14
} 
15
-----------------------------------------------------------------------
16
geo.h
17
-----------------------------------------------------------------------
18
#pragma once
19
#include <cmath>
20
21
struct Coordinates {
22
    double latitude;
23
    double longitude;
24
    
25
    bool operator==(const Coordinates& other) const {
26
        return latitude == other.latitude 
27
            && longitude == other.longitude;
28
    }
29
};
30
31
inline double ComputeDistance(Coordinates start, Coordinates end) {
32
    using namespace std;
33
    if (!(start == end)) {
34
        const double dr = 3.1415926535 / 180.;
35
        return acos(sin(start.latitude * dr) * sin(end.latitude * dr)
36
                    + cos(start.latitude * dr) * cos(end.latitude * dr) 
37
                    * cos(abs(start.longitude - end.longitude) * dr)) * 6371000;
38
    } else {
39
        return 0.0;
40
    }
41
}
42
-----------------------------------------------------------------------
43
input_reader.h
44
-----------------------------------------------------------------------
45
#pragma once
46
#include "transport_catalogue.h"
47
48
Stop split_stop(std::string_view str);
49
std::vector<Distance> split_distance(std::string str, TransportCatalogue& catalogue);
50
Bus split_bus(TransportCatalogue& catalogue, std::string_view str);
51
void input_(TransportCatalogue& catalogue);
52
-----------------------------------------------------------------------
53
stat_reader.h
54
-----------------------------------------------------------------------
55
#pragma once
56
#include "transport_catalogue.h"
57
#include <algorithm>
58
#include <vector>
59
60
void query_stop(TransportCatalogue& catalogue, std::string_view stop_name);
61
void query_(TransportCatalogue& catalogue, std::string_view str);
62
void output_(TransportCatalogue& catalogue);
63
-----------------------------------------------------------------------
64
transport_catalogue.cpp
65
-----------------------------------------------------------------------
66
#include "transport_catalogue.h"
67
68
#include <execution>
69
70
void TransportCatalogue::add_stop(Stop&& stop_) {
71
    stops_.push_back(std::move(stop_));
72
    Stop* stop_buf = &stops_.back();
73
    stopname_to_stop.insert(StopMap::value_type(stop_buf->name_, stop_buf));
74
}
75
76
void TransportCatalogue::add_bus(Bus&& bus_) {
77
    Bus* bus_buf;
78
    buses_.push_back(std::move(bus_)); 
79
    bus_buf = &buses_.back();
80
    busname_to_bus.insert(BusMap::value_type(bus_buf->name_, bus_buf));
81
82
    for (Stop* _stop : bus_buf->stops_) {
83
        _stop->buses_.push_back(bus_buf);
84
    }    
85
}
86
87
void TransportCatalogue::add_distance(std::vector<Distance> distances) {
88
    for (auto distance_ : distances){
89
        auto dist_pair = std::make_pair(distance_.A, distance_.B);
90
        distance_to_stop.insert(DistanceMap::value_type(dist_pair, distance_.distance));
91
    }
92
}
93
94
Bus* TransportCatalogue::get_bus(std::string_view _bus_name) {   
95
    if(busname_to_bus.empty()){
96
        return nullptr;
97
    }
98
    try {
99
        return busname_to_bus.at(_bus_name);
100
    } catch(const std::out_of_range &e) {
101
        return nullptr;
102
    }
103
}
104
105
Stop* TransportCatalogue::get_stop(std::string_view _stop_name) {
106
    if(stopname_to_stop.empty()){
107
        return nullptr;
108
    }
109
    try {
110
        return stopname_to_stop.at(_stop_name);
111
    } catch(const std::out_of_range &e) {
112
        return nullptr;
113
    }
114
}
115
116
std::unordered_set<const Stop*> TransportCatalogue::get_uniq_stops(Bus* bus) {
117
    std::unordered_set<const Stop*> unique_stops_;
118
    
119
    unique_stops_.insert(bus->stops_.begin(), bus->stops_.end());
120
    
121
    return unique_stops_;
122
}
123
124
double TransportCatalogue::get_length(Bus* bus) {
125
    return transform_reduce(next(bus->stops_.begin()), 
126
                            bus->stops_.end(), 
127
                            bus->stops_.begin(),
128
                            0.0,
129
                            std::plus<>{},
130
                            [](const Stop* lhs, const Stop* rhs) { 
131
                                return ComputeDistance({(*lhs).latitude_,
132
                                                        (*lhs).longitude_}, {(*rhs).latitude_,
133
                                                                              (*rhs).longitude_});
134
                            });
135
}
136
137
std::unordered_set<const Bus*> TransportCatalogue::stop_get_uniq_buses(Stop* stop){    
138
    std::unordered_set<const Bus*> unique_stops_;    
139
      
140
    unique_stops_.insert(stop->buses_.begin(), stop->buses_.end());   
141
    
142
    return unique_stops_;
143
}
144
145
size_t TransportCatalogue::get_distance_stop(const Stop* _begin, const Stop* _finish) {
146
    if(distance_to_stop.empty()){
147
        return 0;
148
    }   
149
    try {
150
        auto dist_pair = std::make_pair(_begin, _finish);
151
        return distance_to_stop.at(dist_pair);
152
    } catch (const std::out_of_range &e) {
153
        try {
154
            auto dist_pair = std::make_pair(_finish, _begin);
155
            return distance_to_stop.at(dist_pair);
156
        } catch (const std::out_of_range &e) {
157
            return 0;    
158
        } 
159
    } 
160
}
161
162
size_t TransportCatalogue::get_distance_to_bus(Bus* _bus) {
163
    size_t distance = 0;
164
    auto stops_size = _bus->stops_.size() - 1;
165
    for (int i = 0; i < stops_size; i++) {
166
        distance += get_distance_stop(_bus->stops_[i], _bus->stops_[i+1]);
167
    }
168
    return distance;
169
}
170
-----------------------------------------------------------------------
171
transport_catalogue.h
172
-----------------------------------------------------------------------
173
#pragma once
174
#include <deque>
175
#include <string>
176
#include <vector>
177
178
#include <iomanip>
179
#include <iostream>
180
181
#include <unordered_set>
182
#include <unordered_map>
183
184
#include "geo.h"
185
186
struct Bus;
187
    
188
struct Stop {    
189
    std::string name_;
190
    double latitude_;
191
    double longitude_;
192
    
193
    std::vector<Bus*> buses_;
194
};
195
196
struct Bus { 
197
    std::string name_;
198
    std::vector<Stop*> stops_;
199
};
200
201
struct Distance {    
202
    const Stop* A;
203
    const Stop* B;
204
    int distance;
205
};
206
207
class DistanceHasher {
208
public:
209
    std::size_t operator()(const std::pair<const Stop*, const Stop*> pair_stops) const noexcept {
210
        auto hash_1 = static_cast<const void*>(pair_stops.first);
211
        auto hash_2 = static_cast<const void*>(pair_stops.second);
212
        return hasher_(hash_1) * 17 + hasher_(hash_2);
213
    }
214
private:
215
    std::hash<const void*> hasher_;//struct
216
};
217
218
typedef  std::unordered_map<std::string_view , Stop*> StopMap;
219
typedef  std::unordered_map<std::string_view , Bus*> BusMap;
220
typedef  std::unordered_map<std::pair<const Stop*, const Stop*>, int, DistanceHasher> DistanceMap;
221
222
class TransportCatalogue {
223
public:   
224
    void add_bus(Bus&& bus);
225
    void add_stop(Stop&& stop);
226
    void add_distance(std::vector<Distance> distances);
227
    
228
    Bus* get_bus(std::string_view _bus_name);
229
    Stop* get_stop(std::string_view _stop_name);
230
231
    std::unordered_set<const Bus*> stop_get_uniq_buses(Stop* stop);    
232
    std::unordered_set<const Stop*> get_uniq_stops(Bus* bus);
233
    double get_length(Bus* bus);
234
    
235
    size_t get_distance_stop(const Stop* _start, const Stop* _finish);
236
    size_t get_distance_to_bus(Bus* _bus);
237
private:
238
    std::deque<Stop> stops_;
239
    StopMap stopname_to_stop;
240
    
241
    std::deque<Bus> buses_;
242
    BusMap busname_to_bus;
243
    
244
    DistanceMap distance_to_stop;
245
};
246
-----------------------------------------------------------------------
247
input_reader.cpp
248
-----------------------------------------------------------------------
249
#include "input_reader.h"
250
#include "stat_reader.h"
251
#include <algorithm>
252
253
Stop split_stop(std::string str) {
254
    auto twopoint_pos = str.find(':');
255
    auto comma_pos = str.find(',');
256
    auto entry_length = 5;
257
    auto distance = 2;
258
    Stop _stop;
259
260
    _stop.name_ = str.substr(entry_length, 
261
                                  twopoint_pos - entry_length);
262
    _stop.latitude_ = stod(str.substr(twopoint_pos + distance, 
263
                                      comma_pos - twopoint_pos - distance));
264
    _stop.longitude_ = stod(str.substr(comma_pos + distance));
265
    
266
    return _stop;
267
}
268
269
std::vector<Distance> split_distance(std::string str, TransportCatalogue& catalogue) {
270
    
271
    std::vector<Distance> distances_;
272
    auto entry_length = 5;
273
    auto twopoint_pos = str.find(':');
274
    auto space = 2;
275
    
276
    std::string name_ = str.substr(entry_length, 
277
                                   twopoint_pos - entry_length);
278
    str = str.substr(str.find(',') + 1);
279
    str = str.substr(str.find(',') + space);
280
    
281
    while(str.find(',') != std::string::npos){
282
        
283
        
284
        int distance = stoi(str.substr(0, str.find('m')));
285
        std::string stop_dist_name = str.substr(str.find('m') + entry_length);
286
        stop_dist_name = stop_dist_name.substr(0, stop_dist_name.find(','));
287
        
288
        distances_.push_back({catalogue.get_stop(name_), catalogue.get_stop(stop_dist_name), distance});
289
        
290
        str = str.substr(str.find(',') + space);
291
    }
292
    std::string last_name = str.substr(str.find('m') + entry_length);
293
    int distance = stoi(str.substr(0, str.find('m')));
294
    
295
    distances_.push_back({catalogue.get_stop(name_), catalogue.get_stop(last_name), distance});
296
    return distances_;
297
}
298
299
Bus split_bus(TransportCatalogue& catalogue, std::string_view str) {
300
    auto entry_length = 4;
301
    auto distance = 2;
302
    auto twopoint_pos = str.find(':');
303
    Bus bus;
304
    bus.name_ = str.substr(entry_length, 
305
                           twopoint_pos - entry_length);
306
    
307
    str = str.substr(twopoint_pos + distance);
308
    
309
    auto more_pos = str.find('>');
310
    if (more_pos == std::string_view::npos) {
311
        auto tire_pos = str.find('-');
312
        
313
        while (tire_pos != std::string_view::npos) {
314
            bus.stops_.push_back(catalogue.get_stop(str.substr(0, tire_pos - 1)));
315
            
316
            str = str.substr(tire_pos + distance);
317
            tire_pos = str.find('-');
318
        }
319
        
320
        bus.stops_.push_back(catalogue.get_stop(str.substr(0, tire_pos - 1)));
321
        size_t size_ = bus.stops_.size() - 1;
322
        
323
        for (size_t i = size_; i > 0; i--) {
324
            bus.stops_.push_back(bus.stops_[i-1]);
325
        }
326
        
327
    } else {
328
        while (more_pos != std::string_view::npos) {
329
            bus.stops_.push_back(catalogue.get_stop(str.substr(0, more_pos - 1)));
330
            
331
            str = str.substr(more_pos + distance);
332
            more_pos = str.find('>');
333
        }
334
        
335
        bus.stops_.push_back(catalogue.get_stop(str.substr(0, more_pos - 1)));
336
    }
337
    return bus;
338
}
339
340
void input_(TransportCatalogue& catalogue) {
341
    
342
    std::string count;
343
    std::getline(std::cin, count);
344
    
345
    if (count != "") {
346
        std::string str;
347
        std::vector<std::string> buses;
348
        std::vector<std::string> stops;
349
        int amount = stoi(count);
350
        auto bus_distance = 3;
351
        
352
        for (int i = 0; i < amount; ++i) {
353
            std::getline(std::cin, str);
354
            
355
            if (str != "") {
356
                auto space_pos = str.find_first_not_of(' ');
357
                str = str.substr(space_pos);
358
359
                if (str.substr(0, bus_distance) != "Bus") {
360
                    stops.push_back(str);
361
                } else {
362
                    buses.push_back(str);
363
                }
364
            }
365
        }
366
        
367
        for (auto stop : stops) {
368
           catalogue.add_stop(split_stop(stop));
369
        }
370
        
371
        for (auto stop : stops) {
372
           catalogue.add_distance(split_distance(stop, catalogue));
373
        }
374
        
375
        for (auto bus : buses) {
376
           catalogue.add_bus(split_bus(catalogue, bus));
377
        }
378
    }
379
}
380
-----------------------------------------------------------------------
381
stat_reader.cpp
382
-----------------------------------------------------------------------
383
#include "stat_reader.h"
384
385
void query_bus(TransportCatalogue& catalogue, std::string_view str) {
386
    auto entry = 4;
387
    str = str.substr(entry);
388
    
389
    Bus* bus = catalogue.get_bus(str);
390
    if (bus != nullptr) {
391
        std::cout << "Bus " << bus->name_ << ": "
392
                  << bus->stops_.size() << " stops on route, "
393
                  << (catalogue.get_uniq_stops(bus)).size() << " unique stops, "
394
                  << catalogue.get_distance_to_bus(bus) << " route length, " 
395
                  << std::setprecision(6) << double(catalogue.get_distance_to_bus(bus)
396
                                                    /catalogue.get_length(bus))
397
                  << " curvature" << std::endl;
398
    } else {      
399
        std::cout << "Bus " << str << ": not found" << std::endl;
400
    }  
401
}
402
403
void query_stop(TransportCatalogue& catalogue, std::string_view stop_name) {
404
    auto entry = 5;
405
    stop_name = stop_name.substr(entry);
406
    std::unordered_set<const Bus*> unique_buses;      
407
    std::unordered_set<std::string_view> unique_buses_name;   
408
    std::vector <std::string> bus_name_v;
409
    
410
    Stop* stop = catalogue.get_stop(stop_name);
411
    
412
    if (stop != NULL) {
413
        unique_buses = catalogue.stop_get_uniq_buses(stop);
414
        
415
        if(unique_buses.size() == 0){
416
            std::cout << "Stop " << stop_name << ": no buses" << std::endl;
417
        }
418
        else{
419
            std::cout << "Stop " << stop_name << ": buses ";
420
421
            for (const Bus* _bus : unique_buses) {
422
                bus_name_v.push_back(_bus->name_);
423
            }
424
425
            std::sort(bus_name_v.begin(), bus_name_v.end());         
426
427
            for (std::string_view _bus_name : bus_name_v) {
428
                std::cout << _bus_name;
429
                std::cout << " ";
430
            }
431
            std::cout << std::endl;
432
        }        
433
    } 
434
    else {      
435
        std::cout << "Stop " << stop_name << ": not found" << std::endl;
436
    }
437
}
438
439
void query_(TransportCatalogue& catalogue, std::string_view str) {
440
    if (str.substr(0, 3) == "Bus") {
441
        query_bus(catalogue, str);
442
    } else if (str.substr(0, 4) == "Stop") {
443
        query_stop(catalogue, str);
444
    } else{
445
        std::cout << "Error query" << std::endl;
446
    }
447
}
448
449
void output_(TransportCatalogue& catalogue) {
450
    std::string count;
451
    std::getline(std::cin, count);
452
    
453
    std::string str;
454
    std::vector<std::string> query;
455
    auto amount = stoi(count);
456
    
457
    for (int i = 0; i < amount; ++i) {
458
        std::getline(std::cin, str);
459
        query.push_back(str);
460
    }
461
    
462
    for (auto& strr : query) {
463
        query_(catalogue, strr);
464
    }
465
}