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;
- int main() {
- TransportCatalogue catalogue;
- input_(catalogue);
- output_(catalogue);
- }
- -----------------------------------------------------------------------
- geo.h
- -----------------------------------------------------------------------
- #pragma once
- #include <cmath>
- struct Coordinates {
- double latitude;
- double longitude;
- bool operator==(const Coordinates& other) const {
- return latitude == other.latitude
- && longitude == other.longitude;
- }
- };
- inline double ComputeDistance(Coordinates start, Coordinates end) {
- using namespace std;
- if (!(start == end)) {
- const double dr = 3.1415926535 / 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)) * 6371000;
- } else {
- return 0.0;
- }
- }
- -----------------------------------------------------------------------
- input_reader.h
- -----------------------------------------------------------------------
- #pragma once
- #include "transport_catalogue.h"
- Stop split_stop(std::string_view str);
- std::vector<Distance> split_distance(std::string str, TransportCatalogue& catalogue);
- Bus split_bus(TransportCatalogue& catalogue, std::string_view str);
- void input_(TransportCatalogue& catalogue);
- -----------------------------------------------------------------------
- stat_reader.h
- -----------------------------------------------------------------------
- #pragma once
- #include "transport_catalogue.h"
- #include <algorithm>
- #include <vector>
- void query_stop(TransportCatalogue& catalogue, std::string_view stop_name);
- void query_(TransportCatalogue& catalogue, std::string_view str);
- void output_(TransportCatalogue& catalogue);
- -----------------------------------------------------------------------
- transport_catalogue.cpp
- -----------------------------------------------------------------------
- #include "transport_catalogue.h"
- #include <execution>
- void TransportCatalogue::add_stop(Stop&& stop_) {
- stops_.push_back(std::move(stop_));
- Stop* stop_buf = &stops_.back();
- stopname_to_stop.insert(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);
- }
- }
- void TransportCatalogue::add_distance(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 ComputeDistance({(*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;
- }
- -----------------------------------------------------------------------
- transport_catalogue.h
- -----------------------------------------------------------------------
- #pragma once
- #include <deque>
- #include <string>
- #include <vector>
- #include <iomanip>
- #include <iostream>
- #include <unordered_set>
- #include <unordered_map>
- #include "geo.h"
- struct Bus;
- struct Stop {
- std::string name_;
- double latitude_;
- double longitude_;
- std::vector<Bus*> buses_;
- };
- struct Bus {
- std::string name_;
- std::vector<Stop*> stops_;
- };
- struct Distance {
- const Stop* A;
- const Stop* B;
- int distance;
- };
- class DistanceHasher {
- public:
- 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);
- }
- private:
- std::hash<const void*> hasher_;//struct
- };
- 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(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;
- };
- -----------------------------------------------------------------------
- input_reader.cpp
- -----------------------------------------------------------------------
- #include "input_reader.h"
- #include "stat_reader.h"
- #include <algorithm>
- Stop split_stop(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;
- }
- std::vector<Distance> split_distance(std::string str, TransportCatalogue& catalogue) {
- std::vector<Distance> distances_;
- auto entry_length = 5;
- auto twopoint_pos = str.find(':');
- auto space = 2;
- std::string name_ = str.substr(entry_length,
- twopoint_pos - entry_length);
- str = str.substr(str.find(',') + 1);
- str = str.substr(str.find(',') + space);
- while(str.find(',') != std::string::npos){
- int distance = stoi(str.substr(0, str.find('m')));
- std::string stop_dist_name = str.substr(str.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 = str.substr(str.find(',') + space);
- }
- std::string last_name = str.substr(str.find('m') + entry_length);
- int distance = stoi(str.substr(0, str.find('m')));
- distances_.push_back({catalogue.get_stop(name_), catalogue.get_stop(last_name), distance});
- return distances_;
- }
- Bus split_bus(TransportCatalogue& catalogue, std::string_view str) {
- 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;
- }
- void input_(TransportCatalogue& catalogue) {
- std::string count;
- std::getline(std::cin, 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(std::cin, 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(split_stop(stop));
- }
- for (auto stop : stops) {
- catalogue.add_distance(split_distance(stop, catalogue));
- }
- for (auto bus : buses) {
- catalogue.add_bus(split_bus(catalogue, bus));
- }
- }
- }
- -----------------------------------------------------------------------
- stat_reader.cpp
- -----------------------------------------------------------------------
- #include "stat_reader.h"
- void query_bus(TransportCatalogue& catalogue, std::string_view str) {
- auto entry = 4;
- str = str.substr(entry);
- Bus* bus = catalogue.get_bus(str);
- if (bus != nullptr) {
- std::cout << "Bus " << bus->name_ << ": "
- << bus->stops_.size() << " stops on route, "
- << (catalogue.get_uniq_stops(bus)).size() << " unique stops, "
- << catalogue.get_distance_to_bus(bus) << " route length, "
- << std::setprecision(6) << double(catalogue.get_distance_to_bus(bus)
- /catalogue.get_length(bus))
- << " curvature" << std::endl;
- } else {
- std::cout << "Bus " << str << ": not found" << std::endl;
- }
- }
- void query_stop(TransportCatalogue& catalogue, std::string_view stop_name) {
- auto entry = 5;
- stop_name = stop_name.substr(entry);
- std::unordered_set<const Bus*> unique_buses;
- std::unordered_set<std::string_view> unique_buses_name;
- std::vector <std::string> bus_name_v;
- Stop* stop = catalogue.get_stop(stop_name);
- if (stop != NULL) {
- unique_buses = catalogue.stop_get_uniq_buses(stop);
- if(unique_buses.size() == 0){
- std::cout << "Stop " << stop_name << ": no buses" << std::endl;
- }
- else{
- std::cout << "Stop " << stop_name << ": buses ";
- for (const Bus* _bus : unique_buses) {
- bus_name_v.push_back(_bus->name_);
- }
- std::sort(bus_name_v.begin(), bus_name_v.end());
- for (std::string_view _bus_name : bus_name_v) {
- std::cout << _bus_name;
- std::cout << " ";
- }
- std::cout << std::endl;
- }
- }
- else {
- std::cout << "Stop " << stop_name << ": not found" << std::endl;
- }
- }
- void query_(TransportCatalogue& catalogue, std::string_view str) {
- if (str.substr(0, 3) == "Bus") {
- query_bus(catalogue, str);
- } else if (str.substr(0, 4) == "Stop") {
- query_stop(catalogue, str);
- } else{
- std::cout << "Error query" << std::endl;
- }
- }
- void output_(TransportCatalogue& catalogue) {
- std::string count;
- std::getline(std::cin, count);
- std::string str;
- std::vector<std::string> query;
- auto amount = stoi(count);
- for (int i = 0; i < amount; ++i) {
- std::getline(std::cin, str);
- query.push_back(str);
- }
- for (auto& strr : query) {
- query_(catalogue, strr);
- }
- }
Add Comment
Please, Sign In to add comment