Advertisement
shushus

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

Mar 25th, 2023
597
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.19 KB | None | 0 0
  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. Bus split_bus(TransportCatalogue& catalogue, std::string_view str);
  50. void input_(TransportCatalogue& catalogue);
  51. -----------------------------------------------------------------------
  52. stat_reader.h
  53. -----------------------------------------------------------------------
  54. #pragma once
  55. #include "transport_catalogue.h"
  56. #include <algorithm>
  57. #include <vector>
  58.  
  59. void query_stop(TransportCatalogue& catalogue, std::string_view stop_name);
  60. void query_(TransportCatalogue& catalogue, std::string_view str);
  61. void output_(TransportCatalogue& catalogue);
  62. -----------------------------------------------------------------------
  63. transport_catalogue.cpp
  64. -----------------------------------------------------------------------
  65. #include "transport_catalogue.h"
  66.  
  67. #include <execution>
  68.  
  69. void TransportCatalogue::add_stop(Stop&& stop_) {
  70.     stops_.push_back(std::move(stop_));
  71.     Stop* stop_buf = &stops_.back();
  72.     stopname_to_stop.insert(StopMap::value_type(stop_buf->name_, stop_buf));
  73. }
  74.  
  75. void TransportCatalogue::add_bus(Bus&& bus_) {
  76.     Bus* bus_buf;
  77.     buses_.push_back(std::move(bus_));
  78.     bus_buf = &buses_.back();
  79.     busname_to_bus.insert(BusMap::value_type(bus_buf->name_, bus_buf));
  80.  
  81.     for (Stop* _stop : bus_buf->stops_) {
  82.         _stop->buses_.push_back(bus_buf);
  83.     }    
  84. }
  85.  
  86. Bus* TransportCatalogue::get_bus(std::string_view _bus_name) {  
  87.     if(busname_to_bus.empty()){
  88.         return nullptr;
  89.     }
  90.  
  91.     try {
  92.         return busname_to_bus.at(_bus_name);
  93.     } catch(const std::out_of_range &e) {
  94.         return nullptr;
  95.     }
  96. }
  97.  
  98. Stop* TransportCatalogue::get_stop(std::string_view _stop_name) {
  99.     if(stopname_to_stop.empty()){
  100.         return nullptr;
  101.     }
  102.  
  103.     try {
  104.         return stopname_to_stop.at(_stop_name);
  105.     } catch(const std::out_of_range &e) {
  106.         return nullptr;
  107.     }
  108. }
  109.  
  110. std::unordered_set<const Stop*> TransportCatalogue::get_uniq_stops(Bus* bus) {
  111.     std::unordered_set<const Stop*> unique_stops_;
  112.    
  113.     unique_stops_.insert(bus->stops_.begin(), bus->stops_.end());
  114.    
  115.     return unique_stops_;
  116. }
  117.  
  118. double TransportCatalogue::get_length(Bus* bus) {
  119.     return transform_reduce(next(bus->stops_.begin()),
  120.                             bus->stops_.end(),
  121.                             bus->stops_.begin(),
  122.                             0.0,
  123.                             std::plus<>{},
  124.                             [](const Stop* lhs, const Stop* rhs) {
  125.                                 return ComputeDistance({(*lhs).latitude_,
  126.                                                         (*lhs).longitude_}, {(*rhs).latitude_,
  127.                                                                               (*rhs).longitude_});
  128.                             });
  129. }
  130.  
  131. std::unordered_set<const Bus*> TransportCatalogue::stop_get_uniq_buses(Stop* stop){    
  132.     std::unordered_set<const Bus*> unique_stops_;    
  133.      
  134.     unique_stops_.insert(stop->buses_.begin(), stop->buses_.end());  
  135.    
  136.     return unique_stops_;
  137. }
  138. -----------------------------------------------------------------------
  139. transport_catalogue.h
  140. -----------------------------------------------------------------------
  141. #pragma once
  142. #include <deque>
  143. #include <string>
  144. #include <vector>
  145.  
  146. #include <iomanip>
  147. #include <iostream>
  148.  
  149. #include <unordered_set>
  150. #include <unordered_map>
  151.  
  152. #include "geo.h"
  153.  
  154. struct Bus;
  155.    
  156. struct Stop {    
  157.     std::string name_;
  158.     double latitude_;
  159.     double longitude_;
  160.    
  161.     std::vector<Bus*> buses_;
  162. };
  163.  
  164. struct Bus {
  165.     std::string name_;
  166.     std::vector<Stop*> stops_;
  167. };
  168.  
  169. typedef std::unordered_map<std::string_view , Stop*> StopMap;
  170. typedef std::unordered_map<std::string_view , Bus*> BusMap;
  171.  
  172.  
  173. class TransportCatalogue {
  174. public:  
  175.     void add_bus(Bus&& bus);
  176.     void add_stop(Stop&& stop);
  177.    
  178.     Bus* get_bus(std::string_view _bus_name);
  179.     Stop* get_stop(std::string_view _stop_name);
  180.  
  181.     std::unordered_set<const Bus*> stop_get_uniq_buses(Stop* stop);    
  182.     std::unordered_set<const Stop*> get_uniq_stops(Bus* bus);
  183.     double get_length(Bus* bus);
  184. private:
  185.  
  186.     std::deque<Stop> stops_;
  187.     StopMap stopname_to_stop;
  188.    
  189.     std::deque<Bus> buses_;
  190.     BusMap busname_to_bus;
  191. };
  192. -----------------------------------------------------------------------
  193. input_reader.cpp
  194. -----------------------------------------------------------------------
  195. #include "input_reader.h"
  196. #include "stat_reader.h"
  197. #include <algorithm>
  198.  
  199. Stop split_stop(std::string str) {
  200.     auto twopoint_pos = str.find(':');
  201.     auto comma_pos = str.find(',');
  202.     auto entry_length = 5;
  203.     auto distance = 2;
  204.     Stop _stop;
  205.  
  206.     _stop.name_ = str.substr(entry_length,
  207.                                   twopoint_pos - entry_length);
  208.     _stop.latitude_ = stod(str.substr(twopoint_pos + distance,
  209.                                       comma_pos - twopoint_pos - distance));
  210.     _stop.longitude_ = stod(str.substr(comma_pos + distance));
  211.    
  212.     return _stop;
  213. }
  214.  
  215. Bus split_bus(TransportCatalogue& catalogue, std::string_view str) {
  216.     auto entry_length = 4;
  217.     auto distance = 2;
  218.     auto twopoint_pos = str.find(':');
  219.     Bus bus;
  220.     bus.name_ = str.substr(entry_length,
  221.                            twopoint_pos - entry_length);
  222.    
  223.     str = str.substr(twopoint_pos + distance);
  224.    
  225.     auto more_pos = str.find('>');
  226.     if (more_pos == std::string_view::npos) {
  227.         auto tire_pos = str.find('-');
  228.        
  229.         while (tire_pos != std::string_view::npos) {
  230.             bus.stops_.push_back(catalogue.get_stop(str.substr(0, tire_pos - 1)));
  231.            
  232.             str = str.substr(tire_pos + distance);
  233.             tire_pos = str.find('-');
  234.         }
  235.        
  236.         bus.stops_.push_back(catalogue.get_stop(str.substr(0, tire_pos - 1)));
  237.         size_t size_ = bus.stops_.size() - 1;
  238.        
  239.         for (size_t i = size_; i > 0; i--) {
  240.             bus.stops_.push_back(bus.stops_[i-1]);
  241.         }
  242.        
  243.     } else {
  244.         while (more_pos != std::string_view::npos) {
  245.             bus.stops_.push_back(catalogue.get_stop(str.substr(0, more_pos - 1)));
  246.            
  247.             str = str.substr(more_pos + distance);
  248.             more_pos = str.find('>');
  249.         }
  250.        
  251.         bus.stops_.push_back(catalogue.get_stop(str.substr(0, more_pos - 1)));
  252.     }
  253.     return bus;
  254. }
  255.  
  256. void input_(TransportCatalogue& catalogue) {
  257.    
  258.     std::string count;
  259.     std::getline(std::cin, count);
  260.    
  261.     if (count != "") {
  262.         std::string str;
  263.         std::vector<std::string> buses;
  264.         int amount = stoi(count);
  265.         auto bus_distance = 3;
  266.        
  267.         for (int i = 0; i < amount; ++i) {
  268.             std::getline(std::cin, str);
  269.            
  270.             if (str != "") {
  271.                 auto space_pos = str.find_first_not_of(' ');
  272.                 str = str.substr(space_pos);
  273.  
  274.                 if (str.substr(0, bus_distance) != "Bus") {
  275.                     catalogue.add_stop(split_stop(str));
  276.                 } else {
  277.                     buses.push_back(str);
  278.                 }
  279.             }
  280.         }
  281.        
  282.         for (auto bus : buses) {
  283.             catalogue.add_bus(split_bus(catalogue, bus));
  284.         }
  285.     }
  286. }
  287. -----------------------------------------------------------------------
  288. stat_reader.cpp
  289. -----------------------------------------------------------------------
  290. #include "stat_reader.h"
  291.  
  292. void query_bus(TransportCatalogue& catalogue, std::string_view str) {
  293.     auto entry = 4;
  294.     str = str.substr(entry);
  295.    
  296.     Bus* bus = catalogue.get_bus(str);
  297.     if (bus != nullptr) {
  298.         std::cout << "Bus " << bus->name_ << ": "
  299.                   << bus->stops_.size() << " stops on route, "
  300.                   << (catalogue.get_uniq_stops(bus)).size() << " unique stops, "
  301.                   << std::setprecision(6) << catalogue.get_length(bus) << " route length" << std::endl;
  302.     } else {      
  303.         std::cout << "Bus " << str << ": not found" << std::endl;
  304.     }  
  305. }
  306.  
  307. void query_stop(TransportCatalogue& catalogue, std::string_view stop_name) {
  308.     auto entry = 5;
  309.     stop_name = stop_name.substr(entry);
  310.     std::unordered_set<const Bus*> unique_buses;      
  311.     std::unordered_set<std::string_view> unique_buses_name;  
  312.     std::vector <std::string> bus_name_v;
  313.    
  314.     Stop* stop = catalogue.get_stop(stop_name);
  315.    
  316.     if (stop != NULL) {
  317.         unique_buses = catalogue.stop_get_uniq_buses(stop);
  318.        
  319.         if (unique_buses.size() == 0) {
  320.             std::cout << "Stop " << stop_name << ": no buses" << std::endl;
  321.         } else {
  322.             std::cout << "Stop " << stop_name << ": buses ";
  323.  
  324.             for (const Bus* _bus : unique_buses) {
  325.                 bus_name_v.push_back(_bus->name_);
  326.             }
  327.  
  328.             std::sort(bus_name_v.begin(), bus_name_v.end());        
  329.  
  330.             for (std::string_view _bus_name : bus_name_v) {
  331.                 std::cout << _bus_name;
  332.                 std::cout << " ";
  333.             }
  334.             std::cout << std::endl;
  335.         }        
  336.     }
  337.     else {      
  338.         std::cout << "Stop " << stop_name << ": not found" << std::endl;
  339.     }
  340. }
  341.  
  342. void query_(TransportCatalogue& catalogue, std::string_view str) {
  343.     if (str.substr(0, 3) == "Bus") {
  344.         query_bus(catalogue, str);
  345.     } else if (str.substr(0, 4) == "Stop") {
  346.         query_stop(catalogue, str);
  347.     } else {
  348.         std::cout << "Error query" << std::endl;
  349.     }
  350. }
  351.  
  352. void output_(TransportCatalogue& catalogue) {
  353.     std::string count;
  354.     std::getline(std::cin, count);
  355.    
  356.     std::string str;
  357.     std::vector<std::string> query;
  358.     auto amount = stoi(count);
  359.    
  360.     for (int i = 0; i < amount; ++i) {
  361.         std::getline(std::cin, str);
  362.         query.push_back(str);
  363.     }
  364.    
  365.     for (auto& strr : query) {
  366.         query_(catalogue, strr);
  367.     }
  368. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement