View difference between Paste ID: wENMkn75 and 4Un70dSC
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
using namespace transport_catalogue;
10
using namespace transport_catalogue::detail;
11
12
int main() {
13
    TransportCatalogue catalogue;
14
    fill_catalogue(std::cin, catalogue);
15
    parse_and_execute_queries(std::cin, catalogue);
16
} 
17
-----------------------------------------------------------------------
18
geo.h
19
-----------------------------------------------------------------------
20
#pragma once
21
#include <cmath>
22
23
namespace transport_catalogue {
24
namespace detail {
25
namespace geo {
26
    
27
const int EARTH_RADIUS = 6371000;
28
const double PI = 3.1415926535;
29
    
30
struct Coordinates {
31
    double latitude;
32
    double longitude;
33
    bool operator==(const Coordinates& other) const {
34
        return latitude == other.latitude 
35
            && longitude == other.longitude;
36
    }
37
};
38
    
39
inline double compute_distance(Coordinates start, Coordinates end) {
40
    using namespace std;
41
    if (!(start == end)) {
42
        const double dr = PI / 180.;
43
        return acos(sin(start.latitude * dr) * sin(end.latitude * dr)
44
                    + cos(start.latitude * dr) * cos(end.latitude * dr) 
45
                    * cos(abs(start.longitude - end.longitude) * dr)) * EARTH_RADIUS;
46
    } else {
47
        return 0.0;
48
    }
49
}
50
    
51
}//end namespace geo
52
}//end namespace detail
53
}//end namespace transport_catalogue
54
---------------------------------------------------------------------
55
input_reader.h
56
-----------------------------------------------------------------------
57
#pragma once
58
#include "transport_catalogue.h"
59
60
namespace transport_catalogue {
61
namespace detail {  
62
namespace stop {
63
    Stop parse_stop(const std::string& str);
64
    
65
}//end namespace stop
66
    
67
namespace distance {
68
    std::vector<Distance> parse_distances(const std::string& str, TransportCatalogue& catalogue);
69
    
70
}//end namespace distance
71
    
72
namespace bus {
73
    Bus parse_bus(std::string_view str, TransportCatalogue& catalogue);
74
    
75
}//end namespace bus
76
77
void fill_catalogue(std::istream& input, TransportCatalogue& catalogue);
78
79
}//end namespace detail 
80
}//end namespace transport_catalogue
81
-----------------------------------------------------------------------
82
stat_reader.h
83
-----------------------------------------------------------------------
84
#pragma once
85
#include "transport_catalogue.h"
86
#include <algorithm>
87
#include <vector>
88
89
namespace transport_catalogue {
90
namespace detail {
91
namespace bus {
92
    
93
struct BusQueryResult{
94
    std::string_view name;
95
    bool not_found;
96
    size_t stops_on_route;
97
    size_t unique_stops;
98
    size_t route_length;
99
    double curvature;
100
};
101
    
102
void show_terminal(BusQueryResult bus_info, std::ostream& output);
103
BusQueryResult query(TransportCatalogue& catalogue, std::string_view str);
104
    
105
}//end namespace bus
106
    
107
namespace stop {
108
struct StopQueryResult{
109
    std::string_view name;
110
    bool not_found;
111
    std::vector <std::string_view> buses_name;
112
};
113
    
114
void show_terminal(const StopQueryResult& stop_info, std::ostream& output);
115
StopQueryResult query(TransportCatalogue& catalogue, std::string_view stop_name);
116
    
117
}//end namespace stop
118
    
119
void execute_query(TransportCatalogue& catalogue, std::string_view str);
120
void parse_and_execute_queries(std::istream& input, TransportCatalogue& catalogue);
121
    
122
}//end namespace detail
123
}//end namespace transport_catalogue
124
-----------------------------------------------------------------------
125
transport_catalogue.cpp
126
-----------------------------------------------------------------------
127
#include "transport_catalogue.h"
128
#include <execution>
129
130
namespace transport_catalogue {  
131
    
132
void TransportCatalogue::add_stop(Stop&& stop) {
133
    stops.push_back(std::move(stop));
134
    Stop* stop_buf = &stops.back();
135
    stopname_to_stop.insert(transport_catalogue::StopMap::value_type(stop_buf->name, stop_buf));
136
}
137
138
void TransportCatalogue::add_bus(Bus&& bus) {
139
    Bus* bus_buf;
140
    
141
    buses.push_back(std::move(bus)); 
142
    bus_buf = &buses.back();
143
    busname_to_bus.insert(BusMap::value_type(bus_buf->name, bus_buf));
144
145
    for (Stop* stop : bus_buf->stops) {
146
         stop->buses.push_back(bus_buf);
147
    }
148
    
149
    bus_buf->route_length = get_distance_to_bus(bus_buf);
150
}
151
152
void TransportCatalogue::add_distance(const std::vector<Distance>& distances) {
153
    for (auto distance : distances){
154
        auto dist_pair = std::make_pair(distance.A, distance.B);
155
        distance_to_stop.insert(DistanceMap::value_type(dist_pair, distance.distance));
156
    }
157
}
158
159
Bus* TransportCatalogue::get_bus(std::string_view bus_name) {   
160
    if(busname_to_bus.empty()){
161
        return nullptr;
162
    }
163
    
164
    try{
165
        return busname_to_bus.at(bus_name);
166
    } 
167
    catch(const std::out_of_range &e){
168
        return nullptr;
169
    }
170
}
171
172
Stop* TransportCatalogue::get_stop(std::string_view stop_name) {
173
    if(stopname_to_stop.empty()){
174
        return nullptr;
175
    }
176
    
177
    try {
178
        return stopname_to_stop.at(stop_name);
179
    } catch(const std::out_of_range &e) {
180
        return nullptr;
181
    }
182
}
183
184
std::unordered_set<const Stop*> TransportCatalogue::get_uniq_stops(Bus* bus) {
185
    std::unordered_set<const Stop*> unique_stops;
186
    
187
    unique_stops.insert(bus->stops.begin(), bus->stops.end());
188
    
189
    return unique_stops;
190
}
191
192
double TransportCatalogue::get_length(Bus* bus) {
193
    return transform_reduce(next(bus->stops.begin()), 
194
                            bus->stops.end(), 
195
                            bus->stops.begin(),
196
                            0.0,
197
                            std::plus<>{},
198
                            [](const Stop* lhs, const Stop* rhs) { 
199
                                return detail::geo::compute_distance({(*lhs).latitude,
200
                                                        (*lhs).longitude}, {(*rhs).latitude,
201
                                                                              (*rhs).longitude});
202
                            });
203
}
204
205
std::unordered_set<const Bus*> TransportCatalogue::stop_get_uniq_buses(Stop* stop){    
206
    std::unordered_set<const Bus*> unique_stops;    
207
      
208
    unique_stops.insert(stop->buses.begin(), stop->buses.end());   
209
    
210
    return unique_stops;
211
}
212
213
size_t TransportCatalogue::get_distance_stop(const Stop* begin, const Stop* finish) {
214
    if(distance_to_stop.empty()){
215
        return 0;
216
    }
217
    
218
    try {
219
        
220
        auto dist_pair = std::make_pair(begin, finish);
221
        return distance_to_stop.at(dist_pair);
222
        
223
    } catch(const std::out_of_range &e) {
224
        
225
        try {
226
            auto dist_pair = std::make_pair(finish, begin);
227
            return distance_to_stop.at(dist_pair);
228
        } catch(const std::out_of_range &e) {
229
            return 0;    
230
        } 
231
        
232
    } 
233
}
234
235
size_t TransportCatalogue::get_distance_to_bus(Bus* bus) {
236
    size_t distance = 0;
237
    auto stops_size = bus->stops.size() - 1;
238
    for (int i = 0; i < stops_size; i++) {
239
        distance += get_distance_stop(bus->stops[i], bus->stops[i+1]);
240
    }
241
    return distance;
242
}
243
    
244
}//end namespace transport_catalogue
245
-----------------------------------------------------------------------
246
transport_catalogue.h
247
-----------------------------------------------------------------------
248
#pragma once
249
#include <deque>
250
#include <string>
251
#include <vector>
252
253
#include <iomanip>
254
#include <iostream>
255
256
#include <unordered_set>
257
#include <unordered_map>
258
259
#include "geo.h"
260
261
namespace transport_catalogue {   
262
    
263
struct Bus;
264
    
265
struct Stop {    
266
    std::string name;
267
    double latitude;
268
    double longitude;
269
    
270
    std::vector<Bus*> buses;
271
};
272
273
struct Bus { 
274
    std::string name;
275
    std::vector<Stop*> stops;
276
    size_t route_length;
277
};
278
279
struct Distance {    
280
    const Stop* A;
281
    const Stop* B;
282
    int distance;
283
};
284
285
struct DistanceHasher {
286
    std::hash<const void*> hasher;
287
    
288
    std::size_t operator()(const std::pair<const Stop*, const Stop*> pair_stops) const noexcept {
289
        auto hash_1 = static_cast<const void*>(pair_stops.first);
290
        auto hash_2 = static_cast<const void*>(pair_stops.second);
291
        return hasher(hash_1) * 17 + hasher(hash_2);
292
    }  
293
};
294
    
295
typedef  std::unordered_map<std::string_view, Stop*> StopMap;
296
typedef  std::unordered_map<std::string_view, Bus*> BusMap;
297
typedef  std::unordered_map<std::pair<const Stop*, const  Stop*>, int, DistanceHasher> DistanceMap;
298
299
class TransportCatalogue {
300
public:  
301
    
302
    void add_bus(Bus&& bus);
303
    void add_stop(Stop&& stop);
304
    void add_distance(const std::vector<Distance>& distances);
305
    
306
    Bus* get_bus(std::string_view bus_name);
307
    Stop* get_stop(std::string_view stop_name);
308
309
    std::unordered_set<const Bus*> stop_get_uniq_buses(Stop* stop);    
310
    std::unordered_set<const Stop*> get_uniq_stops(Bus* bus);
311
    double get_length(Bus* bus);
312
    
313
    size_t get_distance_stop(const Stop* start, const Stop* finish);
314
    size_t get_distance_to_bus(Bus* bus);
315
    
316
private:
317
    
318
    std::deque<Stop> stops;
319
    StopMap stopname_to_stop;
320
    
321
    std::deque<Bus> buses;
322
    BusMap busname_to_bus;
323
    
324
    DistanceMap distance_to_stop;
325
    
326
};
327
    
328
}//end namespace transport_catalogue
329
-----------------------------------------------------------------------
330
input_reader.cpp
331
-----------------------------------------------------------------------
332
#include "input_reader.h"
333
#include "stat_reader.h"
334
#include <algorithm>
335
336
namespace transport_catalogue {
337
namespace detail {
338
namespace stop {
339
    
340
Stop parse_stop(const std::string& str) {
341
    auto twopoint_pos = str.find(':');
342
    auto comma_pos = str.find(',');
343
    auto entry_length = 5;
344
    auto distance = 2;
345
    Stop stop;
346
347
    stop.name = str.substr(entry_length, 
348
                             twopoint_pos - entry_length);
349
    stop.latitude = stod(str.substr(twopoint_pos + distance, 
350
                                      comma_pos - twopoint_pos - distance));
351
    stop.longitude = stod(str.substr(comma_pos + distance));
352
    
353
    return stop;
354
}
355
    
356
}//end namespace stop
357
    
358
namespace distance {
359
    
360
std::vector<Distance> parse_distances(const std::string& str, TransportCatalogue& catalogue) {
361
    std::vector<Distance> distances;
362
    auto entry_length = 5;
363
    auto twopoint_pos = str.find(':');
364
    auto space = 2;
365
    
366
    std::string str_copy = str;
367
    std::string name = str_copy.substr(entry_length, 
368
                                   twopoint_pos - entry_length);
369
    str_copy = str_copy.substr(str_copy.find(',') + 1);
370
    str_copy = str_copy.substr(str_copy.find(',') + space);
371
372
    while(str_copy.find(',') != std::string::npos){                    
373
        int distance = stoi(str_copy.substr(0, str_copy.find('m')));
374
        std::string stop_dist_name = str_copy.substr(str_copy.find('m') + entry_length);
375
        stop_dist_name = stop_dist_name.substr(0, stop_dist_name.find(','));
376
        distances.push_back({catalogue.get_stop(name), 
377
                              catalogue.get_stop(stop_dist_name), distance});
378
        str_copy = str_copy.substr(str_copy.find(',') + space);
379
    }
380
    std::string last_name = str_copy.substr(str_copy.find('m') + entry_length);
381
    int distance = stoi(str_copy.substr(0, str_copy.find('m')));
382
    distances.push_back({catalogue.get_stop(name), catalogue.get_stop(last_name), distance});
383
    
384
    return distances;
385
}
386
    
387
}//end namespace distance
388
    
389
namespace bus {
390
    
391
Bus parse_bus(std::string_view str, TransportCatalogue& catalogue) {
392
    auto entry_length = 4;
393
    auto distance = 2;
394
    auto twopoint_pos = str.find(':');
395
    Bus bus;
396
    bus.name = str.substr(entry_length, 
397
                           twopoint_pos - entry_length);
398
399
    str = str.substr(twopoint_pos + distance);
400
401
    auto more_pos = str.find('>');
402
    if (more_pos == std::string_view::npos) {
403
        auto tire_pos = str.find('-');
404
405
        while (tire_pos != std::string_view::npos) {
406
            bus.stops.push_back(catalogue.get_stop(str.substr(0, tire_pos - 1)));
407
408
            str = str.substr(tire_pos + distance);
409
            tire_pos = str.find('-');
410
        }
411
412
        bus.stops.push_back(catalogue.get_stop(str.substr(0, tire_pos - 1)));
413
        size_t size = bus.stops.size() - 1;
414
415
        for (size_t i = size; i > 0; i--) {
416
            bus.stops.push_back(bus.stops[i-1]);
417
        }
418
419
    } else {
420
        while (more_pos != std::string_view::npos) {
421
            bus.stops.push_back(catalogue.get_stop(str.substr(0, more_pos - 1)));
422
423
            str = str.substr(more_pos + distance);
424
            more_pos = str.find('>');
425
        }
426
427
        bus.stops.push_back(catalogue.get_stop(str.substr(0, more_pos - 1)));
428
    }
429
    
430
    return bus;
431
}
432
    
433
}//end namespace bus
434
    
435
void fill_catalogue(std::istream& input, TransportCatalogue& catalogue) {
436
437
    std::string count;
438
    std::getline(input, count);
439
440
    if (count != "") {
441
        std::string str;
442
        std::vector<std::string> buses;
443
        std::vector<std::string> stops;
444
        int amount = stoi(count);
445
        auto bus_distance = 3;
446
447
        for (int i = 0; i < amount; ++i) {
448
            std::getline(input, str);
449
450
            if (str != "") {
451
                auto space_pos = str.find_first_not_of(' ');
452
                str = str.substr(space_pos);
453
454
                if (str.substr(0, bus_distance) != "Bus") {
455
                    stops.push_back(str);
456
                } else {
457
                    buses.push_back(str);
458
                }
459
            }
460
        }
461
462
        for (auto stop : stops) {
463
            catalogue.add_stop(stop::parse_stop(stop));
464
        }
465
466
        for (auto stop : stops) {
467
            catalogue.add_distance(distance::parse_distances(stop, catalogue));
468
        }
469
470
        for (auto bus : buses) {
471
            catalogue.add_bus(bus::parse_bus(bus, catalogue));
472
        }
473
    }
474
}
475
    
476
}//end namespace detail
477
}//end namespace transport_catalogue
478
-----------------------------------------------------------------------
479
stat_reader.cpp
480
-----------------------------------------------------------------------
481
#include "stat_reader.h"
482
483
namespace transport_catalogue { 
484
namespace detail {
485
namespace bus {   
486
    
487
void show_terminal(BusQueryResult bus_info, std::ostream& output) {
488
    if(bus_info.not_found) {
489
        output << "Bus " << bus_info.name << ": not found" << std::endl;
490
    }
491
    else{
492
        output << "Bus " << bus_info.name << ": "
493
               << bus_info.stops_on_route << " stops on route, "
494
               << bus_info.unique_stops << " unique stops, "
495
               << bus_info.route_length << " route length, " 
496
               << std::setprecision(6) << bus_info.curvature
497
               << " curvature" << std::endl;
498
    }
499
}
500
BusQueryResult query(TransportCatalogue& catalogue, std::string_view bus_name) {
501
    BusQueryResult bus_info;
502
    auto entry = 4;
503
    bus_name = bus_name.substr(entry);
504
505
    Bus* bus = catalogue.get_bus(bus_name);
506
    if (bus != nullptr) {                
507
        bus_info.name = bus->name;
508
        bus_info.not_found = false;
509
        bus_info.stops_on_route = bus->stops.size();
510
        bus_info.unique_stops = catalogue.get_uniq_stops(bus).size();
511
        bus_info.route_length = bus->route_length;
512
        bus_info.curvature = double(catalogue.get_distance_to_bus(bus)
513
                                    /catalogue.get_length(bus));                    
514
    } else {  
515
        bus_info.name = bus_name;
516
        bus_info.not_found = true;
517
    }
518
    return bus_info;
519
}
520
    
521
}//end namespace bus
522
    
523
namespace stop {   
524
    
525
void show_terminal(const StopQueryResult& stop_info, std::ostream& output) {
526
    if(stop_info.not_found) {
527
        output << "Stop " << stop_info.name << ": not found" << std::endl;
528
    } else {
529
        if(stop_info.buses_name.size() == 0){
530
            output << "Stop " << stop_info.name << ": no buses" << std::endl;
531
        } else {
532
            output << "Stop " << stop_info.name << ": buses ";
533
534
            for (std::string_view bus_name : stop_info.buses_name) {
535
                 output << bus_name;
536
                 output << " ";
537
            }
538
            output << std::endl;
539
        }
540
    }
541
}
542
    
543
StopQueryResult query(TransportCatalogue& catalogue, std::string_view stop_name) {
544
    auto entry = 5;
545
    stop_name = stop_name.substr(entry);
546
    std::unordered_set<const Bus*> unique_buses;
547
548
    StopQueryResult stop_info;
549
550
    Stop* stop = catalogue.get_stop(stop_name);
551
552
    if (stop != NULL) {
553
        stop_info.name = stop->name;
554
        stop_info.not_found = false;
555
        unique_buses = catalogue.stop_get_uniq_buses(stop);
556
        
557
        if(unique_buses.size() > 0){
558
            for (const Bus* bus : unique_buses) {
559
                stop_info.buses_name.push_back(bus->name);
560
            }
561
            std::sort(stop_info.buses_name.begin(), stop_info.buses_name.end());
562
        }        
563
    } 
564
    else {    
565
        stop_info.name = stop_name;
566
        stop_info.not_found = true;
567
    }
568
    return stop_info;
569
}
570
    
571
}//end namespace stop
572
    
573
void execute_query(TransportCatalogue& catalogue, std::string_view str) {
574
    if (str.substr(0, 3) == "Bus") {
575
        bus::show_terminal(bus::query(catalogue, str), std::cout);
576
    } else if (str.substr(0, 4) == "Stop") {
577
        stop::show_terminal(stop::query(catalogue, str), std::cout);
578
    } else{
579
        std::cout << "Error query" << std::endl;
580
    }
581
}
582
583
void parse_and_execute_queries(std::istream& input, TransportCatalogue& catalogue) {
584
    std::string count;
585
    std::getline(input, count);
586
    
587
    std::string str;
588
    std::vector<std::string> query;
589
    auto amount = stoi(count);
590
    
591
    for (int i = 0; i < amount; ++i) {
592
        std::getline(input, str);
593
        query.push_back(str);
594
    }
595
    
596
    for (auto& strr : query) {
597
        execute_query(catalogue, strr);
598
    }
599
}
600
    
601
}//end namespace detail
602
}//end namespace transport_catalogue