Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -----------------------------------------------------------------------
- main.cpp
- -----------------------------------------------------------------------
- #include "transport_catalogue.h"
- #include "input_reader.h"
- #include "stat_reader.h"
- using namespace std;
- using namespace transport_catalogue;
- using namespace transport_catalogue::detail;
- int main() {
- TransportCatalogue catalogue;
- fill_catalogue(std::cin, catalogue);
- parse_and_execute_queries(std::cin, catalogue);
- }
- -----------------------------------------------------------------------
- geo.h
- -----------------------------------------------------------------------
- #pragma once
- #include <cmath>
- namespace transport_catalogue {
- namespace detail {
- namespace geo {
- const int EARTH_RADIUS = 6371000;
- const double PI = 3.1415926535;
- struct Coordinates {
- double latitude;
- double longitude;
- bool operator==(const Coordinates& other) const {
- return latitude == other.latitude
- && longitude == other.longitude;
- }
- };
- inline double compute_distance(Coordinates start, Coordinates end) {
- using namespace std;
- if (!(start == end)) {
- const double dr = PI / 180.;
- return acos(sin(start.latitude * dr) * sin(end.latitude * dr)
- + cos(start.latitude * dr) * cos(end.latitude * dr)
- * cos(abs(start.longitude - end.longitude) * dr)) * EARTH_RADIUS;
- } else {
- return 0.0;
- }
- }
- }//end namespace geo
- }//end namespace detail
- }//end namespace transport_catalogue
- ---------------------------------------------------------------------
- input_reader.h
- -----------------------------------------------------------------------
- #pragma once
- #include "transport_catalogue.h"
- namespace transport_catalogue {
- namespace detail {
- namespace stop {
- Stop parse_stop(const std::string& str);
- }//end namespace stop
- namespace distance {
- std::vector<Distance> parse_distances(const std::string& str, TransportCatalogue& catalogue);
- }//end namespace distance
- namespace bus {
- Bus parse_bus(std::string_view str, TransportCatalogue& catalogue);
- }//end namespace bus
- void fill_catalogue(std::istream& input, TransportCatalogue& catalogue);
- }//end namespace detail
- }//end namespace transport_catalogue
- -----------------------------------------------------------------------
- stat_reader.h
- -----------------------------------------------------------------------
- #pragma once
- #include "transport_catalogue.h"
- #include <algorithm>
- #include <vector>
- namespace transport_catalogue {
- namespace detail {
- namespace bus {
- struct BusQueryResult{
- std::string_view name;
- bool not_found;
- size_t stops_on_route;
- size_t unique_stops;
- size_t route_length;
- double curvature;
- };
- void show_terminal(BusQueryResult bus_info, std::ostream& output);
- BusQueryResult query(TransportCatalogue& catalogue, std::string_view str);
- }//end namespace bus
- namespace stop {
- struct StopQueryResult{
- std::string_view name;
- bool not_found;
- std::vector <std::string_view> buses_name;
- };
- void show_terminal(const StopQueryResult& stop_info, std::ostream& output);
- StopQueryResult query(TransportCatalogue& catalogue, std::string_view stop_name);
- }//end namespace stop
- void execute_query(TransportCatalogue& catalogue, std::string_view str);
- void parse_and_execute_queries(std::istream& input, TransportCatalogue& catalogue);
- }//end namespace detail
- }//end namespace transport_catalogue
- -----------------------------------------------------------------------
- transport_catalogue.cpp
- -----------------------------------------------------------------------
- #include "transport_catalogue.h"
- #include <execution>
- namespace transport_catalogue {
- void TransportCatalogue::add_stop(Stop&& stop) {
- stops.push_back(std::move(stop));
- Stop* stop_buf = &stops.back();
- stopname_to_stop.insert(transport_catalogue::StopMap::value_type(stop_buf->name, stop_buf));
- }
- void TransportCatalogue::add_bus(Bus&& bus) {
- Bus* bus_buf;
- buses.push_back(std::move(bus));
- bus_buf = &buses.back();
- busname_to_bus.insert(BusMap::value_type(bus_buf->name, bus_buf));
- for (Stop* stop : bus_buf->stops) {
- stop->buses.push_back(bus_buf);
- }
- bus_buf->route_length = get_distance_to_bus(bus_buf);
- }
- void TransportCatalogue::add_distance(const std::vector<Distance>& distances) {
- for (auto distance : distances){
- auto dist_pair = std::make_pair(distance.A, distance.B);
- distance_to_stop.insert(DistanceMap::value_type(dist_pair, distance.distance));
- }
- }
- Bus* TransportCatalogue::get_bus(std::string_view bus_name) {
- if(busname_to_bus.empty()){
- return nullptr;
- }
- try{
- return busname_to_bus.at(bus_name);
- }
- catch(const std::out_of_range &e){
- return nullptr;
- }
- }
- Stop* TransportCatalogue::get_stop(std::string_view stop_name) {
- if(stopname_to_stop.empty()){
- return nullptr;
- }
- try {
- return stopname_to_stop.at(stop_name);
- } catch(const std::out_of_range &e) {
- return nullptr;
- }
- }
- std::unordered_set<const Stop*> TransportCatalogue::get_uniq_stops(Bus* bus) {
- std::unordered_set<const Stop*> unique_stops;
- unique_stops.insert(bus->stops.begin(), bus->stops.end());
- return unique_stops;
- }
- double TransportCatalogue::get_length(Bus* bus) {
- return transform_reduce(next(bus->stops.begin()),
- bus->stops.end(),
- bus->stops.begin(),
- 0.0,
- std::plus<>{},
- [](const Stop* lhs, const Stop* rhs) {
- return detail::geo::compute_distance({(*lhs).latitude,
- (*lhs).longitude}, {(*rhs).latitude,
- (*rhs).longitude});
- });
- }
- std::unordered_set<const Bus*> TransportCatalogue::stop_get_uniq_buses(Stop* stop){
- std::unordered_set<const Bus*> unique_stops;
- unique_stops.insert(stop->buses.begin(), stop->buses.end());
- return unique_stops;
- }
- size_t TransportCatalogue::get_distance_stop(const Stop* begin, const Stop* finish) {
- if(distance_to_stop.empty()){
- return 0;
- }
- try {
- auto dist_pair = std::make_pair(begin, finish);
- return distance_to_stop.at(dist_pair);
- } catch(const std::out_of_range &e) {
- try {
- auto dist_pair = std::make_pair(finish, begin);
- return distance_to_stop.at(dist_pair);
- } catch(const std::out_of_range &e) {
- return 0;
- }
- }
- }
- size_t TransportCatalogue::get_distance_to_bus(Bus* bus) {
- size_t distance = 0;
- auto stops_size = bus->stops.size() - 1;
- for (int i = 0; i < stops_size; i++) {
- distance += get_distance_stop(bus->stops[i], bus->stops[i+1]);
- }
- return distance;
- }
- }//end namespace transport_catalogue
- -----------------------------------------------------------------------
- transport_catalogue.h
- -----------------------------------------------------------------------
- #pragma once
- #include <deque>
- #include <string>
- #include <vector>
- #include <iomanip>
- #include <iostream>
- #include <unordered_set>
- #include <unordered_map>
- #include "geo.h"
- namespace transport_catalogue {
- struct Bus;
- struct Stop {
- std::string name;
- double latitude;
- double longitude;
- std::vector<Bus*> buses;
- };
- struct Bus {
- std::string name;
- std::vector<Stop*> stops;
- size_t route_length;
- };
- struct Distance {
- const Stop* A;
- const Stop* B;
- int distance;
- };
- struct DistanceHasher {
- std::hash<const void*> hasher;
- std::size_t operator()(const std::pair<const Stop*, const Stop*> pair_stops) const noexcept {
- auto hash_1 = static_cast<const void*>(pair_stops.first);
- auto hash_2 = static_cast<const void*>(pair_stops.second);
- return hasher(hash_1) * 17 + hasher(hash_2);
- }
- };
- typedef std::unordered_map<std::string_view, Stop*> StopMap;
- typedef std::unordered_map<std::string_view, Bus*> BusMap;
- typedef std::unordered_map<std::pair<const Stop*, const Stop*>, int, DistanceHasher> DistanceMap;
- class TransportCatalogue {
- public:
- void add_bus(Bus&& bus);
- void add_stop(Stop&& stop);
- void add_distance(const std::vector<Distance>& distances);
- Bus* get_bus(std::string_view bus_name);
- Stop* get_stop(std::string_view stop_name);
- std::unordered_set<const Bus*> stop_get_uniq_buses(Stop* stop);
- std::unordered_set<const Stop*> get_uniq_stops(Bus* bus);
- double get_length(Bus* bus);
- size_t get_distance_stop(const Stop* start, const Stop* finish);
- size_t get_distance_to_bus(Bus* bus);
- private:
- std::deque<Stop> stops;
- StopMap stopname_to_stop;
- std::deque<Bus> buses;
- BusMap busname_to_bus;
- DistanceMap distance_to_stop;
- };
- }//end namespace transport_catalogue
- -----------------------------------------------------------------------
- input_reader.cpp
- -----------------------------------------------------------------------
- #include "input_reader.h"
- #include "stat_reader.h"
- #include <algorithm>
- namespace transport_catalogue {
- namespace detail {
- namespace stop {
- Stop parse_stop(const std::string& str) {
- auto twopoint_pos = str.find(':');
- auto comma_pos = str.find(',');
- auto entry_length = 5;
- auto distance = 2;
- Stop stop;
- stop.name = str.substr(entry_length,
- twopoint_pos - entry_length);
- stop.latitude = stod(str.substr(twopoint_pos + distance,
- comma_pos - twopoint_pos - distance));
- stop.longitude = stod(str.substr(comma_pos + distance));
- return stop;
- }
- }//end namespace stop
- namespace distance {
- std::vector<Distance> parse_distances(const std::string& str, TransportCatalogue& catalogue) {
- std::vector<Distance> distances;
- auto entry_length = 5;
- auto twopoint_pos = str.find(':');
- auto space = 2;
- std::string str_copy = str;
- std::string name = str_copy.substr(entry_length,
- twopoint_pos - entry_length);
- str_copy = str_copy.substr(str_copy.find(',') + 1);
- str_copy = str_copy.substr(str_copy.find(',') + space);
- while(str_copy.find(',') != std::string::npos){
- int distance = stoi(str_copy.substr(0, str_copy.find('m')));
- std::string stop_dist_name = str_copy.substr(str_copy.find('m') + entry_length);
- stop_dist_name = stop_dist_name.substr(0, stop_dist_name.find(','));
- distances.push_back({catalogue.get_stop(name),
- catalogue.get_stop(stop_dist_name), distance});
- str_copy = str_copy.substr(str_copy.find(',') + space);
- }
- std::string last_name = str_copy.substr(str_copy.find('m') + entry_length);
- int distance = stoi(str_copy.substr(0, str_copy.find('m')));
- distances.push_back({catalogue.get_stop(name), catalogue.get_stop(last_name), distance});
- return distances;
- }
- }//end namespace distance
- namespace bus {
- Bus parse_bus(std::string_view str, TransportCatalogue& catalogue) {
- auto entry_length = 4;
- auto distance = 2;
- auto twopoint_pos = str.find(':');
- Bus bus;
- bus.name = str.substr(entry_length,
- twopoint_pos - entry_length);
- str = str.substr(twopoint_pos + distance);
- auto more_pos = str.find('>');
- if (more_pos == std::string_view::npos) {
- auto tire_pos = str.find('-');
- while (tire_pos != std::string_view::npos) {
- bus.stops.push_back(catalogue.get_stop(str.substr(0, tire_pos - 1)));
- str = str.substr(tire_pos + distance);
- tire_pos = str.find('-');
- }
- bus.stops.push_back(catalogue.get_stop(str.substr(0, tire_pos - 1)));
- size_t size = bus.stops.size() - 1;
- for (size_t i = size; i > 0; i--) {
- bus.stops.push_back(bus.stops[i-1]);
- }
- } else {
- while (more_pos != std::string_view::npos) {
- bus.stops.push_back(catalogue.get_stop(str.substr(0, more_pos - 1)));
- str = str.substr(more_pos + distance);
- more_pos = str.find('>');
- }
- bus.stops.push_back(catalogue.get_stop(str.substr(0, more_pos - 1)));
- }
- return bus;
- }
- }//end namespace bus
- void fill_catalogue(std::istream& input, TransportCatalogue& catalogue) {
- std::string count;
- std::getline(input, count);
- if (count != "") {
- std::string str;
- std::vector<std::string> buses;
- std::vector<std::string> stops;
- int amount = stoi(count);
- auto bus_distance = 3;
- for (int i = 0; i < amount; ++i) {
- std::getline(input, str);
- if (str != "") {
- auto space_pos = str.find_first_not_of(' ');
- str = str.substr(space_pos);
- if (str.substr(0, bus_distance) != "Bus") {
- stops.push_back(str);
- } else {
- buses.push_back(str);
- }
- }
- }
- for (auto stop : stops) {
- catalogue.add_stop(stop::parse_stop(stop));
- }
- for (auto stop : stops) {
- catalogue.add_distance(distance::parse_distances(stop, catalogue));
- }
- for (auto bus : buses) {
- catalogue.add_bus(bus::parse_bus(bus, catalogue));
- }
- }
- }
- }//end namespace detail
- }//end namespace transport_catalogue
- -----------------------------------------------------------------------
- stat_reader.cpp
- -----------------------------------------------------------------------
- #include "stat_reader.h"
- namespace transport_catalogue {
- namespace detail {
- namespace bus {
- void show_terminal(BusQueryResult bus_info, std::ostream& output) {
- if(bus_info.not_found) {
- output << "Bus " << bus_info.name << ": not found" << std::endl;
- }
- else{
- output << "Bus " << bus_info.name << ": "
- << bus_info.stops_on_route << " stops on route, "
- << bus_info.unique_stops << " unique stops, "
- << bus_info.route_length << " route length, "
- << std::setprecision(6) << bus_info.curvature
- << " curvature" << std::endl;
- }
- }
- BusQueryResult query(TransportCatalogue& catalogue, std::string_view bus_name) {
- BusQueryResult bus_info;
- auto entry = 4;
- bus_name = bus_name.substr(entry);
- Bus* bus = catalogue.get_bus(bus_name);
- if (bus != nullptr) {
- bus_info.name = bus->name;
- bus_info.not_found = false;
- bus_info.stops_on_route = bus->stops.size();
- bus_info.unique_stops = catalogue.get_uniq_stops(bus).size();
- bus_info.route_length = bus->route_length;
- bus_info.curvature = double(catalogue.get_distance_to_bus(bus)
- /catalogue.get_length(bus));
- } else {
- bus_info.name = bus_name;
- bus_info.not_found = true;
- }
- return bus_info;
- }
- }//end namespace bus
- namespace stop {
- void show_terminal(const StopQueryResult& stop_info, std::ostream& output) {
- if(stop_info.not_found) {
- output << "Stop " << stop_info.name << ": not found" << std::endl;
- } else {
- if(stop_info.buses_name.size() == 0){
- output << "Stop " << stop_info.name << ": no buses" << std::endl;
- } else {
- output << "Stop " << stop_info.name << ": buses ";
- for (std::string_view bus_name : stop_info.buses_name) {
- output << bus_name;
- output << " ";
- }
- output << std::endl;
- }
- }
- }
- StopQueryResult query(TransportCatalogue& catalogue, std::string_view stop_name) {
- auto entry = 5;
- stop_name = stop_name.substr(entry);
- std::unordered_set<const Bus*> unique_buses;
- StopQueryResult stop_info;
- Stop* stop = catalogue.get_stop(stop_name);
- if (stop != NULL) {
- stop_info.name = stop->name;
- stop_info.not_found = false;
- unique_buses = catalogue.stop_get_uniq_buses(stop);
- if(unique_buses.size() > 0){
- for (const Bus* bus : unique_buses) {
- stop_info.buses_name.push_back(bus->name);
- }
- std::sort(stop_info.buses_name.begin(), stop_info.buses_name.end());
- }
- }
- else {
- stop_info.name = stop_name;
- stop_info.not_found = true;
- }
- return stop_info;
- }
- }//end namespace stop
- void execute_query(TransportCatalogue& catalogue, std::string_view str) {
- if (str.substr(0, 3) == "Bus") {
- bus::show_terminal(bus::query(catalogue, str), std::cout);
- } else if (str.substr(0, 4) == "Stop") {
- stop::show_terminal(stop::query(catalogue, str), std::cout);
- } else{
- std::cout << "Error query" << std::endl;
- }
- }
- void parse_and_execute_queries(std::istream& input, TransportCatalogue& catalogue) {
- std::string count;
- std::getline(input, count);
- std::string str;
- std::vector<std::string> query;
- auto amount = stoi(count);
- for (int i = 0; i < amount; ++i) {
- std::getline(input, str);
- query.push_back(str);
- }
- for (auto& strr : query) {
- execute_query(catalogue, strr);
- }
- }
- }//end namespace detail
- }//end namespace transport_catalogue
Add Comment
Please, Sign In to add comment