delix777

Спринт 10. Транспортный справочник - пишем код. Задание 3.

Nov 25th, 2025
44
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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. }
Add Comment
Please, Sign In to add comment