shushus

Спринт 11. Транспортный справочник - поддержка JSON.

Apr 6th, 2023 (edited)
1,320
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 36.89 KB | None | 0 0
  1. -----------------------------------------------------------------------
  2. domain.h
  3. -----------------------------------------------------------------------
  4. #pragma once
  5.  
  6. #include "transport_catalogue.h"
  7. #include <algorithm>
  8. #include <vector>
  9.  
  10. namespace transport_catalogue {
  11. namespace detail {
  12. namespace bus {
  13.    
  14. struct BusQueryResult{
  15.     std::string_view name;
  16.     bool not_found;
  17.     int stops_on_route;
  18.     int unique_stops;
  19.     int route_length;
  20.     double curvature;
  21. };
  22.    
  23. void show_terminal(BusQueryResult bus_info, std::ostream& output);
  24. BusQueryResult query(TransportCatalogue& catalogue, std::string_view str);
  25.    
  26. }//end namespace bus
  27.    
  28. namespace stop {
  29.    
  30. struct StopQueryResult{
  31.     std::string_view name;
  32.     bool not_found;
  33.     std::vector <std::string> buses_name;
  34. };
  35.    
  36. void show_terminal(const StopQueryResult& stop_info, std::ostream& output);
  37. StopQueryResult query(TransportCatalogue& catalogue, std::string_view stop_name);
  38.    
  39. }//end namespace stop
  40.    
  41. void execute_query(TransportCatalogue& catalogue, std::string_view str);
  42. void parse_and_execute_queries(TransportCatalogue& catalogue);
  43.    
  44. }//end namespace detail
  45. }//end namespace transport_catalogue
  46. -----------------------------------------------------------------------
  47. domain.cpp
  48. -----------------------------------------------------------------------
  49. #include "domain.h"
  50.  
  51. namespace transport_catalogue {
  52. namespace detail {
  53. namespace bus {  
  54.    
  55. void show_terminal(BusQueryResult bus_info, std::ostream& output) {
  56.     if (bus_info.not_found) {
  57.         output << "Bus " << bus_info.name << ": not found" << std::endl;
  58.     } else {
  59.         output << "Bus " << bus_info.name << ": "
  60.                << bus_info.stops_on_route << " stops on route, "
  61.                << bus_info.unique_stops << " unique stops, "
  62.                << bus_info.route_length << " route length, "
  63.                << std::setprecision(6) << bus_info.curvature
  64.                << " curvature" << std::endl;
  65.     }
  66. }
  67.    
  68. BusQueryResult query(TransportCatalogue& catalogue, std::string_view bus_name) {
  69.     BusQueryResult bus_info;
  70.  
  71.     Bus* bus = catalogue.get_bus(bus_name);
  72.     if (bus != nullptr) {                
  73.         bus_info.name = bus->name;
  74.         bus_info.not_found = false;
  75.         bus_info.stops_on_route = bus->stops.size();
  76.         bus_info.unique_stops = catalogue.get_uniq_stops(bus).size();
  77.         bus_info.route_length = bus->route_length;
  78.         bus_info.curvature = double(catalogue.get_distance_to_bus(bus)
  79.                                     /catalogue.get_length(bus));                    
  80.     } else {  
  81.         bus_info.name = bus_name;
  82.         bus_info.not_found = true;
  83.     }
  84.    
  85.     return bus_info;
  86. }
  87.    
  88. }//end namespace bus
  89.    
  90. namespace stop {  
  91.    
  92. void show_terminal(const StopQueryResult& stop_info, std::ostream& output) {
  93.    
  94.     if (stop_info.not_found) {
  95.         output << "Stop " << stop_info.name << ": not found" << std::endl;
  96.        
  97.     } else {
  98.        
  99.         if (stop_info.buses_name.size() == 0) {
  100.             output << "Stop " << stop_info.name << ": no buses" << std::endl;
  101.         } else {
  102.             output << "Stop " << stop_info.name << ": buses ";
  103.  
  104.             for (std::string_view bus_name : stop_info.buses_name) {
  105.                  output << bus_name;
  106.                  output << " ";
  107.             }
  108.            
  109.             output << std::endl;
  110.         }
  111.     }
  112. }
  113.    
  114. StopQueryResult query(TransportCatalogue& catalogue, std::string_view stop_name) {
  115.     std::unordered_set<const Bus*> unique_buses;
  116.  
  117.     StopQueryResult stop_info;
  118.  
  119.     Stop* stop = catalogue.get_stop(stop_name);
  120.  
  121.     if (stop != NULL) {
  122.        
  123.         stop_info.name = stop->name;
  124.         stop_info.not_found = false;
  125.         unique_buses = catalogue.stop_get_uniq_buses(stop);
  126.        
  127.         if (unique_buses.size() > 0) {
  128.            
  129.             for (const Bus* bus : unique_buses) {
  130.                 stop_info.buses_name.push_back(bus->name);
  131.             }
  132.            
  133.             std::sort(stop_info.buses_name.begin(), stop_info.buses_name.end());
  134.         }    
  135.        
  136.     } else {    
  137.         stop_info.name = stop_name;
  138.         stop_info.not_found = true;
  139.     }
  140.    
  141.     return stop_info;
  142. }
  143.    
  144. }//end namespace stop
  145.    
  146. void execute_query(TransportCatalogue& catalogue, std::string_view str) {
  147.     if (str.substr(0, 3) == "Bus") {
  148.         bus::show_terminal(bus::query(catalogue, str), std::cout);
  149.        
  150.     } else if (str.substr(0, 4) == "Stop") {
  151.         stop::show_terminal(stop::query(catalogue, str), std::cout);
  152.        
  153.     } else {
  154.         std::cout << "Error query" << std::endl;
  155.     }
  156. }
  157.  
  158. void parse_and_execute_queries(TransportCatalogue& catalogue) {
  159.     std::vector<std::string> query;
  160.    
  161.     query.push_back("Bus 114");
  162.     query.push_back("Stop Морской вокзал");
  163.     query.push_back("Stop Ривьерский мост");
  164.    
  165.     for (auto& strr : query) {
  166.         execute_query(catalogue, strr);
  167.     }
  168. }
  169.    
  170. }//end namespace detail
  171. }//end namespace transport_catalogue
  172. -----------------------------------------------------------------------
  173. geo.h
  174. -----------------------------------------------------------------------
  175. #pragma once
  176. #include <cmath>
  177.  
  178. namespace transport_catalogue {
  179. namespace detail {
  180. namespace geo {
  181.    
  182. const int EARTH_RADIUS = 6371000;
  183. const double PI = 3.1415926535;
  184.    
  185. struct Coordinates {
  186.     double latitude;
  187.     double longitude;
  188.  
  189.     bool operator==(const Coordinates& other) const {
  190.         return latitude == other.latitude && longitude == other.longitude;
  191.     }
  192.     bool operator!=(const Coordinates& other) const {
  193.         return !(*this == other);
  194.     }
  195. };
  196.    
  197. double compute_distance(Coordinates start, Coordinates end);
  198.    
  199. }//end namespace geo
  200. }//end namespace detail
  201. }//end namespace transport_catalogue
  202. -----------------------------------------------------------------------
  203. geo.cpp
  204. -----------------------------------------------------------------------
  205. #define _USE_MATH_DEFINES
  206. #include "geo.h"
  207.  
  208. #include <cmath>
  209.  
  210. namespace transport_catalogue {
  211. namespace detail {
  212. namespace geo {
  213.    
  214. double compute_distance(Coordinates start, Coordinates end) {
  215.     using namespace std;
  216.    
  217.     if (!(start == end)) {
  218.         const double dr = PI / 180.;
  219.         return acos(sin(start.latitude * dr) * sin(end.latitude * dr)
  220.                     + cos(start.latitude * dr) * cos(end.latitude * dr)
  221.                     * cos(abs(start.longitude - end.longitude) * dr)) * EARTH_RADIUS;
  222.     } else {
  223.         return 0.0;
  224.     }
  225. }
  226.    
  227. }//end namespace geo
  228. }//end namespace detail
  229. }//end namespace transport_catalogue
  230. -----------------------------------------------------------------------
  231. json.h
  232. -----------------------------------------------------------------------
  233. #pragma once
  234. /*
  235.  * Место для вашей JSON-библиотеки
  236.  */
  237. #pragma once
  238.  
  239. #include <iostream>
  240. #include <map>
  241. #include <string>
  242. #include <vector>
  243. #include <variant>
  244.  
  245. namespace transport_catalogue {
  246. namespace detail {
  247. namespace json {
  248.  
  249. class Node;
  250.  
  251. using Dict = std::map<std::string, Node>;
  252. using Array = std::vector<Node>;
  253.  
  254. class ParsingError : public std::runtime_error {
  255. public:
  256.     using runtime_error::runtime_error;
  257. };
  258.  
  259. class Node {
  260. public:
  261.     using Value =  std::variant<std::nullptr_t, Array, Dict, bool, int, double, std::string>;
  262.  
  263.     Node() = default;
  264.     Node(bool value);
  265.     Node(Array array);
  266.     Node(Dict map);
  267.     Node(int value);
  268.     Node(std::string value);
  269.     Node(std::nullptr_t);
  270.     Node(double value);
  271.    
  272.     const Array& AsArray() const;
  273.     const Dict& AsMap() const;
  274.     int AsInt() const;
  275.     double AsDouble() const;
  276.     bool AsBool() const;
  277.     const std::string& AsString() const;
  278.  
  279.     bool IsNull() const;
  280.     bool IsInt() const;
  281.     bool IsDouble() const;
  282.     bool IsPureDouble() const;
  283.     bool IsBool() const;
  284.     bool IsString() const;
  285.     bool IsArray() const;
  286.     bool IsMap() const;
  287.  
  288.     const Value& GetValue() const { return value_; };
  289.        
  290. private:
  291.     Value value_;
  292. };
  293.  
  294. inline bool operator==(const Node& lhs, const Node& rhs) {
  295.     return lhs.GetValue() == rhs.GetValue();
  296. }
  297.    
  298. inline bool operator!=(const Node& lhs, const Node& rhs) {
  299.     return !(lhs == rhs);
  300. }
  301.    
  302. class Document {
  303. public:
  304.     explicit Document(Node root);
  305.     Document() = default;
  306.     const Node& GetRoot() const;
  307.  
  308. private:
  309.     Node root_;
  310. };
  311.  
  312. Document Load(std::istream& input);
  313.  
  314. inline bool operator==(const Document& lhs, const Document& rhs) {
  315.     return lhs.GetRoot() == rhs.GetRoot();
  316. }
  317.  
  318. inline bool operator!=(const Document& lhs, const Document& rhs) {
  319.     return !(lhs == rhs);
  320. }
  321.    
  322. void Print(const Document& doc, std::ostream& output);
  323.  
  324. }//end namespace json
  325. }//end namespace detail
  326. }//end namespace transport_catalogue
  327. -----------------------------------------------------------------------
  328. json.cpp
  329. -----------------------------------------------------------------------
  330. #include "json.h"
  331.  
  332. using namespace std;
  333.  
  334. namespace transport_catalogue {
  335. namespace detail {
  336. namespace json {
  337.  
  338. namespace {
  339.    
  340. Node LoadNode(istream& input);
  341.  
  342. std::string LoadLiteral(std::istream& input) {
  343.     std::string str;
  344.     while (std::isalpha(input.peek())) {
  345.         str.push_back(static_cast<char>(input.get()));
  346.     }
  347.  
  348.     return str;
  349. }
  350.  
  351. Node LoadArray(std::istream& input) {
  352.  
  353.     std::vector<Node> result;
  354.     for (char current_char; input >> current_char && current_char != ']';) {
  355.         if (current_char != ',') {
  356.             input.putback(current_char);
  357.         }
  358.         result.push_back(LoadNode(input));
  359.     }
  360.  
  361.     if (!input) {
  362.         throw ParsingError("Array parsing error"s);
  363.     }
  364.  
  365.     return Node(result);
  366. }
  367.  
  368. Node LoadNull(std::istream& input) {
  369.     if (auto literal = LoadLiteral(input); literal == "null"sv) {
  370.         return Node{ nullptr };
  371.     } else {
  372.         throw ParsingError("Failed to parse '"s + literal + "' as null"s);
  373.     }
  374. }
  375.  
  376. Node LoadBool(std::istream& input) {
  377.     const auto str = LoadLiteral(input);
  378.  
  379.     if (str == "true"sv) {
  380.         return Node{ true };
  381.     } else if (str == "false"sv) {
  382.         return Node{ false };
  383.     } else {
  384.         throw ParsingError("Failed to parse '"s + str + "' as bool"s);
  385.     }
  386. }
  387.  
  388. Node LoadNumber(std::istream& input) {
  389.     std::string parsed_num;
  390.  
  391.     auto read_char = [&parsed_num, &input] {
  392.         parsed_num += static_cast<char>(input.get());
  393.         if (!input) {
  394.             throw ParsingError("Failed to read number from stream"s);
  395.         }
  396.     };
  397.  
  398.     auto read_digits = [&input, read_char] {
  399.         if (!std::isdigit(input.peek())) {
  400.             throw ParsingError("A digit is expected"s);
  401.         }
  402.         while (std::isdigit(input.peek())) {
  403.             read_char();
  404.         }
  405.     };
  406.  
  407.     if (input.peek() == '-') {
  408.         read_char();
  409.     }
  410.  
  411.     if (input.peek() == '0') {
  412.         read_char();
  413.     } else {
  414.         read_digits();
  415.     }
  416.  
  417.     bool is_int = true;
  418.     if (input.peek() == '.') {
  419.         read_char();
  420.         read_digits();
  421.         is_int = false;
  422.     }
  423.  
  424.     if (int current_char = input.peek(); current_char == 'e' || current_char == 'E') {
  425.         read_char();
  426.         if (current_char = input.peek(); current_char == '+' || current_char == '-') {
  427.             read_char();
  428.         }
  429.  
  430.         read_digits();
  431.         is_int = false;
  432.     }
  433.  
  434.     try {
  435.         if (is_int) {
  436.             try {
  437.                 return Node(std::stoi(parsed_num));
  438.             } catch (...) {
  439.             }
  440.         }
  441.  
  442.         return Node(std::stod(parsed_num));
  443.     } catch (...) {
  444.         throw ParsingError("Failed to convert "s + parsed_num + " to number"s);
  445.     }
  446. }
  447.  
  448. Node LoadString(std::istream& input) {
  449.     auto it = std::istreambuf_iterator<char>(input);
  450.     auto end = std::istreambuf_iterator<char>();
  451.    
  452.     std::string str;
  453.    
  454.     while (true) {
  455.         if (it == end) {
  456.             throw ParsingError("String parsing error");
  457.         }
  458.         const char current_char = *it;
  459.         if (current_char == '"') {
  460.             ++it;
  461.             break;
  462.         } else if (current_char == '\\') {
  463.             ++it;
  464.             if (it == end) {
  465.                 throw ParsingError("String parsing error");
  466.             }
  467.             const char escaped_char = *(it);
  468.             switch (escaped_char) {
  469.                 case 'n':
  470.                     str.push_back('\n');
  471.                     break;
  472.                 case 't':
  473.                     str.push_back('\t');
  474.                     break;
  475.                 case 'r':
  476.                     str.push_back('\r');
  477.                     break;
  478.                 case '"':
  479.                     str.push_back('"');
  480.                     break;
  481.                 case '\\':
  482.                     str.push_back('\\');
  483.                     break;
  484.                 default:
  485.                     throw ParsingError("Unrecognized escape sequence \\"s + escaped_char);
  486.             }
  487.         } else if (current_char == '\n' || current_char == '\r') {
  488.             throw ParsingError("Unexpected end of line"s);
  489.         } else {
  490.             str.push_back(current_char);
  491.         }
  492.         ++it;
  493.     }
  494.     return Node(str);
  495. }
  496.    
  497. Node LoadDict(std::istream& input) {
  498.     Dict dict;
  499.  
  500.     for (char current_char; input >> current_char && current_char != '}';) {
  501.         if (current_char == '"') {
  502.             std::string key = LoadString(input).AsString();
  503.  
  504.             if (input >> current_char && current_char == ':') {
  505.                 if (dict.find(key) != dict.end()) {
  506.                     throw ParsingError("Duplicate key '"s + key + "' have been found");
  507.                 }
  508.  
  509.                 dict.emplace(std::move(key), LoadNode(input));
  510.             } else {
  511.                 throw ParsingError(": is expected but '"s + current_char + "' has been found"s);
  512.             }
  513.         } else if (current_char != ',') {
  514.             throw ParsingError(R"(',' is expected but ')"s + current_char + "' has been found"s);
  515.         }
  516.     }
  517.  
  518.     if (!input) {
  519.         throw ParsingError("Dictionary parsing error"s);
  520.     }
  521.  
  522.     return Node(dict);
  523. }
  524.  
  525.  
  526. Node LoadNode(std::istream& input) {
  527.     char c;
  528.     if (!(input >> c)) {
  529.         throw ParsingError(""s);
  530.     }
  531.     switch (c) {
  532.         case '[':
  533.             return LoadArray(input);
  534.         case '{':
  535.             return LoadDict(input);
  536.         case '"':
  537.             return LoadString(input);
  538.         case 't': case 'f':
  539.             input.putback(c);
  540.             return LoadBool(input);
  541.         case 'n':
  542.             input.putback(c);
  543.             return LoadNull(input);
  544.         default:
  545.             input.putback(c);
  546.             return LoadNumber(input);
  547.     }
  548. }    
  549. }  // namespace
  550.    
  551. Node::Node(Array array) :
  552.     value_(std::move(array)) {        
  553.     }
  554.    
  555.  Node::Node(std::nullptr_t) :
  556.     Node() {}
  557.  
  558. Node::Node(bool value)
  559.     : value_(value) {
  560. }
  561.  
  562. Node::Node(Dict map)
  563.     : value_(move(map)) {
  564. }
  565.  
  566. Node::Node(int value)
  567.     : value_(value) {
  568. }
  569.  
  570. Node::Node(string value)
  571.     : value_(move(value)) {
  572. }
  573.  
  574. Node::Node(double value)
  575.     : value_(value) {
  576. }
  577.    
  578. const Array& Node::AsArray() const {
  579.     using namespace std::literals;
  580.     if (!IsArray()) {
  581.         throw std::logic_error("Error: not array"s);
  582.     }
  583.     return std::get<Array>(value_);
  584. }
  585.  
  586. const Dict& Node::AsMap() const {
  587.     using namespace std::literals;
  588.     if (!IsMap()) {
  589.         throw std::logic_error("Error: not dict"s);
  590.     }
  591.     return std::get<Dict>(value_);
  592. }
  593.  
  594. const string& Node::AsString() const {
  595.     using namespace std::literals;
  596.     if (!IsString()) {
  597.         throw std::logic_error("Error: not string"s);
  598.     }
  599.     return std::get<std::string>(value_);
  600. }
  601.    
  602. int Node::AsInt() const {
  603.     using namespace std::literals;    
  604.     if (!IsInt()) {
  605.         throw std::logic_error("Error: not int"s);
  606.     }
  607.     return std::get<int>(value_);
  608. }
  609.  
  610. double Node::AsDouble() const {
  611.     using namespace std::literals;
  612.     if (!IsDouble()) {
  613.         throw std::logic_error("Error: not double"s);
  614.     }
  615.     if(IsPureDouble()){
  616.         return std::get<double>(value_);
  617.     }
  618.     else{
  619.         return AsInt();
  620.     }    
  621. }
  622.  
  623. bool Node::AsBool() const {
  624.     using namespace std::literals;
  625.     if (!IsBool()) {
  626.         throw std::logic_error("Error: not bool"s);
  627.     }
  628.     return std::get<bool>(value_);
  629. }
  630.    
  631. bool Node::IsNull() const {
  632.     return std::holds_alternative<std::nullptr_t>(value_);
  633. }
  634.    
  635. bool Node::IsInt() const {
  636.     return std::holds_alternative<int>(value_);
  637. }
  638.  
  639. bool Node::IsDouble() const {
  640.     return IsInt() || IsPureDouble();
  641. }
  642.    
  643. bool Node::IsPureDouble() const {
  644.     return std::holds_alternative<double>(value_);
  645. }
  646.    
  647. bool Node::IsBool() const {
  648.     return std::holds_alternative<bool>(value_);
  649. }
  650.    
  651. bool Node::IsString() const {
  652.     return std::holds_alternative<std::string>(value_);
  653. }
  654.    
  655. bool Node::IsArray() const {
  656.     return std::holds_alternative<Array>(value_);
  657. }
  658.    
  659. bool Node::IsMap() const {
  660.     return std::holds_alternative<Dict>(value_);
  661. }
  662.    
  663.    
  664. Document::Document(Node root)
  665.     : root_(move(root)) {
  666. }
  667.  
  668. const Node& Document::GetRoot() const {
  669.     return root_;
  670. }
  671.  
  672. Document Load(istream& input) {
  673.     return Document{LoadNode(input)};
  674. }
  675.  
  676. struct PrintContext {
  677.     std::ostream& out;
  678.     int indent_step = 4;
  679.     int indent = 0;
  680.  
  681.     void PrintIndent() const {
  682.         for (int i = 0; i < indent; ++i) {
  683.             out.put(' ');
  684.         }
  685.     }
  686.  
  687.     [[nodiscard]] PrintContext Indented() const {
  688.         return { out, indent_step, indent_step + indent };
  689.     }
  690. };
  691.  
  692. void PrintNode(const Node& node, const PrintContext& ctx);
  693.  
  694. template <typename Value>
  695. void PrintValue(const Value& value, const PrintContext& ctx) {
  696.     ctx.out << value;
  697. }
  698.  
  699. void PrintString(const std::string& value, std::ostream& out) {
  700.     out.put('"');
  701.     for (const char current_char : value) {
  702.         switch (current_char) {
  703.             case '\r':
  704.                 out << R"(\r)";
  705.                 break;
  706.             case '\n':
  707.                 out << R"(\n)";
  708.                 break;
  709.             case '"':
  710.                 out << R"(\")";
  711.                 break;
  712.             case '\\':
  713.                 out << R"(\\)";
  714.                 break;
  715.             default:
  716.                 out.put(current_char);
  717.                 break;
  718.         }
  719.     }
  720.     out.put('"');
  721. }
  722.  
  723.     template <>
  724.     void PrintValue<std::string>(const std::string& value, const PrintContext& ctx) {
  725.         PrintString(value, ctx.out);
  726.     }
  727.  
  728. void PrintValue(const std::nullptr_t&, const PrintContext& ctx) {
  729.     ctx.out << "null"s;
  730. }
  731.  
  732. void PrintValue(bool value, const PrintContext& ctx) {
  733.     ctx.out << std::boolalpha << value;
  734. }
  735.  
  736. [[maybe_unused]] void PrintValue(Array nodes, const PrintContext& ctx) {
  737.     std::ostream& out = ctx.out;
  738.  
  739.     out << "[\n"sv;
  740.  
  741.     bool first = true;
  742.     auto inner_ctx = ctx.Indented();
  743.     for (const Node& node : nodes) {
  744.         if (first) {
  745.             first = false;
  746.         } else {
  747.             out << ",\n"sv;
  748.         }
  749.  
  750.         inner_ctx.PrintIndent();
  751.         PrintNode(node, inner_ctx);
  752.     }
  753.  
  754.     out.put('\n');
  755.     ctx.PrintIndent();
  756.     out.put(']');
  757. }
  758.  
  759. [[maybe_unused]] void PrintValue(Dict nodes, const PrintContext& ctx) {
  760.     std::ostream& out = ctx.out;
  761.  
  762.     out << "{\n"sv;
  763.  
  764.     bool first = true;
  765.     auto inner_ctx = ctx.Indented();
  766.     for (const auto& [key, node] : nodes) {
  767.         if (first) {
  768.             first = false;
  769.         } else {
  770.             out << ",\n"sv;
  771.         }
  772.  
  773.         inner_ctx.PrintIndent();
  774.         PrintString(key, ctx.out);
  775.         out << ": "sv;
  776.         PrintNode(node, inner_ctx);
  777.     }
  778.  
  779.     out.put('\n');
  780.     ctx.PrintIndent();
  781.     out.put('}');
  782. }
  783.  
  784. void PrintNode(const Node& node, const PrintContext& ctx) {
  785.     std::visit(
  786.         [&ctx](const auto& value) {
  787.             PrintValue(value, ctx);
  788.         },
  789.         node.GetValue());
  790. }
  791.    
  792. void Print(const Document& doc, std::ostream& output) {
  793.     PrintNode(doc.GetRoot(), PrintContext{ output });
  794. }
  795.  
  796. }//end namespace json
  797. }//end namespace detail
  798. }//end namespace transport_catalogue
  799. -----------------------------------------------------------------------
  800. json_reader.h
  801. -----------------------------------------------------------------------
  802. #pragma once
  803. #include "json.h"
  804. #include "transport_catalogue.h"
  805. #include "domain.h"
  806.  
  807. namespace transport_catalogue {
  808. namespace detail {
  809. namespace json {
  810.    
  811. using namespace transport_catalogue::detail::stop;
  812. using namespace transport_catalogue::detail::bus;
  813.    
  814. struct StatRequest {
  815.     int id;
  816.     std::string type;
  817.     std::string name;    
  818. };
  819.    
  820. void ParseNode(const Node& root, TransportCatalogue& catalogue, std::vector<StatRequest>& stat_request);
  821. void Parse(Document& doc, TransportCatalogue& catalogue, std::vector<StatRequest>& stat_request);
  822. void ParseNodeBase(const Node& root, TransportCatalogue& catalogue);
  823. void ParceNodeStat(const Node& root, std::vector<StatRequest>& stat_request);
  824.  
  825. Stop ParseNodeStop(Node& node);
  826. std::vector<Distance> ParseNodeDistances(Node& node, TransportCatalogue& catalogue);
  827. Bus ParseNodeBus(Node& node, TransportCatalogue& catalogue);
  828.    
  829. Document ExecuteQueries(TransportCatalogue& catalogue, std::vector<StatRequest>& stat_requests);
  830. Node ExecuteMakeNodeStop(int id_request, StopQueryResult query_result);
  831. Node ExecuteMakeNodeBus(int id_request, BusQueryResult query_result);
  832.    
  833. }//end namespace json
  834. }//end namespace detail
  835. }//end namespace transport_catalogue
  836. -----------------------------------------------------------------------
  837. json_reader.cpp
  838. -----------------------------------------------------------------------
  839. #include "json_reader.h"
  840.  
  841. namespace transport_catalogue {
  842. namespace detail {
  843. namespace json {
  844.  
  845. void Parse(Document& doc, TransportCatalogue& catalogue, std::vector<StatRequest>& stat_request) {
  846.     ParseNode(doc.GetRoot(),
  847.               catalogue,
  848.               stat_request);
  849. }
  850.    
  851. void ParseNode(const Node& root, TransportCatalogue& catalogue, std::vector<StatRequest>& stat_request) {  
  852.     Dict root_dict;
  853.    
  854.     if (root.IsMap()) {
  855.         root_dict = root.AsMap();
  856.  
  857.         try {          
  858.             ParseNodeBase(root_dict.at("base_requests"), catalogue);
  859.         } catch(...) {
  860.             std::cout << "Error: base_requests is empty";
  861.         }
  862.  
  863.         try {
  864.             ParceNodeStat(root_dict.at("stat_requests"), stat_request);
  865.         } catch(...) {
  866.             std::cout << "Error: stat_requests is empty";
  867.         }
  868.        
  869.     } else {
  870.         std::cout << "Error: root is not map";
  871.     }
  872. }
  873.  
  874. void ParseNodeBase(const Node& root, TransportCatalogue& catalogue) {
  875.     Array base_requests;
  876.     Dict req_map;
  877.     Node req_node;
  878.    
  879.     std::vector<Node> buses;
  880.     std::vector<Node> stops;
  881.    
  882.     if (root.IsArray()) {
  883.         base_requests = root.AsArray();
  884.        
  885.         for (Node& node : base_requests) {            
  886.             if (node.IsMap()) {
  887.                 req_map = node.AsMap();
  888.                
  889.                 try {
  890.                     req_node = req_map.at("type");
  891.                     if (req_node.IsString()) {
  892.                        
  893.                         if (req_node.AsString() == "Bus") {
  894.                             buses.push_back(req_map);
  895.                            
  896.                         } else if (req_node.AsString() == "Stop") {
  897.                             stops.push_back(req_map);
  898.                            
  899.                         } else {
  900.                             std::cout << "Error: base_requests have bad type";
  901.                         }
  902.                     }
  903.                    
  904.                 } catch(...) {
  905.                     std::cout << "Error: base_requests not have type value";
  906.                 }                
  907.             }
  908.         }  
  909.        
  910.         for (auto stop : stops) {
  911.             catalogue.add_stop(ParseNodeStop(stop));
  912.         }
  913.        
  914.         for (auto stop : stops) {
  915.             catalogue.add_distance(ParseNodeDistances(stop, catalogue));
  916.         }
  917.        
  918.         for (auto bus : buses) {
  919.             catalogue.add_bus(ParseNodeBus(bus, catalogue));
  920.         }
  921.        
  922.     } else {
  923.         std::cout << "Error: base_requests is not array";
  924.     }
  925. }
  926.  
  927. Stop ParseNodeStop(Node& node) {
  928.     Stop stop;
  929.     Dict stop_node;
  930.    
  931.     if (node.IsMap()) {
  932.        
  933.         stop_node = node.AsMap();
  934.         stop.name = stop_node.at("name").AsString();
  935.         stop.latitude = stop_node.at("latitude").AsDouble();
  936.         stop.longitude = stop_node.at("longitude").AsDouble();
  937.     }
  938.    
  939.     return stop;
  940. }
  941.    
  942. std::vector<Distance> ParseNodeDistances(Node& node, TransportCatalogue& catalogue) {
  943.     std::vector<Distance> distances;
  944.     Dict stop_node;
  945.     Dict stop_road_map;
  946.     std::string begin_name;
  947.     std::string last_name;
  948.     int distance;
  949.    
  950.     if (node.IsMap()) {
  951.         stop_node = node.AsMap();
  952.         begin_name = stop_node.at("name").AsString();
  953.        
  954.         try {
  955.             stop_road_map = stop_node.at("road_distances").AsMap();
  956.            
  957.             for (auto [key, value] : stop_road_map) {
  958.                 last_name = key;
  959.                 distance = value.AsInt();
  960.                 distances.push_back({catalogue.get_stop(begin_name),
  961.                                      catalogue.get_stop(last_name),
  962.                                      distance});
  963.             }            
  964.         }
  965.        
  966.         catch(...) {
  967.             std::cout << "Error: Road invalide" << std::endl;
  968.         }        
  969.     }
  970.    
  971.     return distances;
  972. }
  973.  
  974. Bus ParseNodeBus(Node& node, [[maybe_unused]] TransportCatalogue& catalogue) {
  975.     Bus bus;
  976.     Dict bus_node;
  977.     Array bus_stops;
  978.    
  979.     if (node.IsMap()) {
  980.         bus_node = node.AsMap();
  981.         bus.name = bus_node.at("name").AsString();
  982.         bus.is_roundtrip = bus_node.at("is_roundtrip").AsBool();
  983.        
  984.         try {
  985.             bus_stops = bus_node.at("stops").AsArray();
  986.            
  987.             for (Node stop : bus_stops) {
  988.                 bus.stops.push_back(catalogue.get_stop(stop.AsString()));
  989.             }
  990.  
  991.             if (!bus.is_roundtrip) {
  992.                 size_t size = bus.stops.size() - 1;
  993.                
  994.                 for (size_t i = size; i > 0; i--) {
  995.                     bus.stops.push_back(bus.stops[i-1]);
  996.                 }
  997.             }  
  998.            
  999.         } catch(...) {
  1000.             std::cout << "Error: base_requests: bus: stops is empty" << std::endl;
  1001.         }        
  1002.     }
  1003.    
  1004.     return bus;
  1005. }
  1006.  
  1007. void ParceNodeStat(const Node& node, std::vector<StatRequest>& stat_request) {
  1008.     Array stat_requests;
  1009.     Dict req_map;
  1010.     StatRequest req;
  1011.    
  1012.     if (node.IsArray()) {
  1013.         stat_requests = node.AsArray();
  1014.        
  1015.         for (Node req_node : stat_requests) {
  1016.            
  1017.             if (req_node.IsMap()) {
  1018.                
  1019.                 req_map = req_node.AsMap();
  1020.                 req.id = req_map.at("id").AsInt();
  1021.                 req.type = req_map.at("type").AsString();
  1022.                 req.name = req_map.at("name").AsString();
  1023.                 stat_request.push_back(req);
  1024.             }
  1025.         }
  1026.        
  1027.     } else {
  1028.         std::cout << "Error: base_requests is not array";
  1029.     }
  1030. }
  1031.  
  1032. Document ExecuteQueries([[maybe_unused]] TransportCatalogue& catalogue, std::vector<StatRequest>& stat_requests) {
  1033.     std::vector<Node> result_request;
  1034.    
  1035.     for (StatRequest req : stat_requests) {
  1036.        
  1037.         if (req.type == "Stop") {
  1038.             result_request.push_back(ExecuteMakeNodeStop(req.id, stop::query(catalogue,
  1039.                                                                              req.name)));
  1040.  
  1041.         } else if(req.type == "Bus") {
  1042.             result_request.push_back(ExecuteMakeNodeBus(req.id,bus::query(catalogue,
  1043.                                                                           req.name)));
  1044.         }        
  1045.     }
  1046.     return Document{Node{result_request}};
  1047. }
  1048.  
  1049. Node ExecuteMakeNodeStop(int id_request, StopQueryResult stop_info) {
  1050.     Dict result;
  1051.     Array buses;
  1052.     std::string str_not_found = "not found";
  1053.    
  1054.     if (stop_info.not_found) {
  1055.         result.emplace("request_id", Node{id_request});
  1056.         result.emplace("error_message", Node{str_not_found});
  1057.        
  1058.     } else {
  1059.         result.emplace("request_id", Node{id_request});
  1060.        
  1061.         for (std::string bus_name : stop_info.buses_name) {
  1062.             buses.push_back(Node{bus_name});
  1063.         }
  1064.        
  1065.         result.emplace("buses", Node{buses});
  1066.     }
  1067.    
  1068.     return Node{result};
  1069. }
  1070.  
  1071. Node ExecuteMakeNodeBus(int id_request, BusQueryResult bus_info) {
  1072.     Dict result;
  1073.     std::string str_not_found = "not found";
  1074.    
  1075.     if (bus_info.not_found) {
  1076.         result.emplace("request_id", Node{id_request});
  1077.         result.emplace("error_message", Node{str_not_found});
  1078.        
  1079.     } else {
  1080.         result.emplace("request_id", Node{id_request});        
  1081.         result.emplace("curvature", Node{bus_info.curvature});
  1082.         result.emplace("route_length", Node{bus_info.route_length});
  1083.         result.emplace("stop_count", Node{bus_info.stops_on_route});
  1084.         result.emplace("unique_stop_count", Node{bus_info.unique_stops});
  1085.        
  1086.     }
  1087.    
  1088.     return Node{result};
  1089. }
  1090.    
  1091. }//end namespace json
  1092. }//end namespace detail
  1093. }//end namespace transport_catalogue
  1094. -----------------------------------------------------------------------
  1095. main.cpp
  1096. -----------------------------------------------------------------------
  1097. #include "transport_catalogue.h"
  1098. #include "json_reader.h"
  1099. #include "domain.h"
  1100.  
  1101. using namespace std;
  1102. using namespace transport_catalogue;
  1103. using namespace transport_catalogue::detail;
  1104. using namespace transport_catalogue::detail::json;
  1105.  
  1106. int main() {
  1107.     std::vector<StatRequest> stat_request;
  1108.    
  1109.     TransportCatalogue catalogue;
  1110.    
  1111.     Document doc_in;
  1112.     Document doc_out;
  1113.    
  1114.     doc_in = json::Load(std::cin);
  1115.    
  1116.     json::Parse(doc_in, catalogue, stat_request);
  1117.     doc_out = json::ExecuteQueries(catalogue, stat_request);
  1118.     Print(doc_out, std::cout);
  1119. }
  1120. -----------------------------------------------------------------------
  1121. map_renderer.h
  1122. -----------------------------------------------------------------------
  1123.  
  1124. empty
  1125.  
  1126. -----------------------------------------------------------------------
  1127. map_renderer.cpp
  1128. -----------------------------------------------------------------------
  1129.  
  1130. empty
  1131.  
  1132. -----------------------------------------------------------------------
  1133. request_handler.h
  1134. -----------------------------------------------------------------------
  1135.  
  1136. empty
  1137.  
  1138. -----------------------------------------------------------------------
  1139. request_handler.cpp
  1140. -----------------------------------------------------------------------
  1141.  
  1142. empty
  1143.  
  1144. -----------------------------------------------------------------------
  1145. svg.h
  1146. -----------------------------------------------------------------------
  1147.  
  1148. empty
  1149.  
  1150. -----------------------------------------------------------------------
  1151. svg.cpp
  1152. -----------------------------------------------------------------------
  1153.  
  1154. empty
  1155.  
  1156. -----------------------------------------------------------------------
  1157. transport_catalogue.h
  1158. -----------------------------------------------------------------------
  1159. #pragma once
  1160. #include <deque>
  1161. #include <string>
  1162. #include <vector>
  1163.  
  1164. #include <iomanip>
  1165. #include <iostream>
  1166.  
  1167. #include <unordered_set>
  1168. #include <unordered_map>
  1169.  
  1170. #include "geo.h"
  1171.  
  1172. namespace transport_catalogue {  
  1173.    
  1174. struct Bus;
  1175.    
  1176. struct Stop {    
  1177.     std::string name;
  1178.     double latitude;
  1179.     double longitude;
  1180.    
  1181.     std::vector<Bus*> buses;
  1182. };
  1183.  
  1184. struct Bus {
  1185.     std::string name;
  1186.     std::vector<Stop*> stops;
  1187.     bool is_roundtrip;
  1188.     size_t route_length;
  1189. };
  1190.  
  1191. struct Distance {    
  1192.     const Stop* A;
  1193.     const Stop* B;
  1194.     int distance;
  1195. };
  1196.  
  1197. struct DistanceHasher {
  1198.     std::hash<const void*> hasher;
  1199.    
  1200.     std::size_t operator()(const std::pair<const Stop*, const Stop*> pair_stops) const noexcept {
  1201.         auto hash_1 = static_cast<const void*>(pair_stops.first);
  1202.         auto hash_2 = static_cast<const void*>(pair_stops.second);
  1203.         return hasher(hash_1) * 17 + hasher(hash_2);
  1204.     }  
  1205. };
  1206.    
  1207. typedef  std::unordered_map<std::string_view, Stop*> StopMap;
  1208. typedef  std::unordered_map<std::string_view, Bus*> BusMap;
  1209. typedef  std::unordered_map<std::pair<const Stop*, const  Stop*>, int, DistanceHasher> DistanceMap;
  1210.  
  1211. class TransportCatalogue {
  1212. public:  
  1213.    
  1214.     void add_bus(Bus&& bus);
  1215.     void add_stop(Stop&& stop);
  1216.     void add_distance(const std::vector<Distance>& distances);
  1217.    
  1218.     Bus* get_bus(std::string_view bus_name);
  1219.     Stop* get_stop(std::string_view stop_name);
  1220.  
  1221.     std::unordered_set<const Bus*> stop_get_uniq_buses(Stop* stop);    
  1222.     std::unordered_set<const Stop*> get_uniq_stops(Bus* bus);
  1223.     double get_length(Bus* bus);
  1224.    
  1225.     size_t get_distance_stop(const Stop* start, const Stop* finish);
  1226.     size_t get_distance_to_bus(Bus* bus);
  1227.    
  1228. private:
  1229.    
  1230.     std::deque<Stop> stops;
  1231.     StopMap stopname_to_stop;
  1232.    
  1233.     std::deque<Bus> buses;
  1234.     BusMap busname_to_bus;
  1235.    
  1236.     DistanceMap distance_to_stop;
  1237.    
  1238. };
  1239.    
  1240. }//end namespace transport_catalogue
  1241. -----------------------------------------------------------------------
  1242. transport_catalogue.cpp
  1243. -----------------------------------------------------------------------
  1244. #include "transport_catalogue.h"
  1245. #include <execution>
  1246.  
  1247. namespace transport_catalogue {  
  1248.    
  1249. void TransportCatalogue::add_stop(Stop&& stop) {
  1250.     stops.push_back(std::move(stop));
  1251.     Stop* stop_buf = &stops.back();
  1252.     stopname_to_stop.insert(transport_catalogue::StopMap::value_type(stop_buf->name, stop_buf));
  1253. }
  1254.  
  1255. void TransportCatalogue::add_bus(Bus&& bus) {
  1256.     Bus* bus_buf;
  1257.    
  1258.     buses.push_back(std::move(bus));
  1259.     bus_buf = &buses.back();
  1260.     busname_to_bus.insert(BusMap::value_type(bus_buf->name, bus_buf));
  1261.  
  1262.     for (Stop* stop : bus_buf->stops) {
  1263.          stop->buses.push_back(bus_buf);
  1264.     }
  1265.    
  1266.     bus_buf->route_length = get_distance_to_bus(bus_buf);
  1267. }
  1268.  
  1269. void TransportCatalogue::add_distance(const std::vector<Distance>& distances) {
  1270.     for (auto distance : distances){
  1271.         auto dist_pair = std::make_pair(distance.A, distance.B);
  1272.         distance_to_stop.insert(DistanceMap::value_type(dist_pair, distance.distance));
  1273.     }
  1274. }
  1275.  
  1276. Bus* TransportCatalogue::get_bus(std::string_view bus_name) {  
  1277.     if(busname_to_bus.empty()){
  1278.         return nullptr;
  1279.     }
  1280.    
  1281.     try{
  1282.         return busname_to_bus.at(bus_name);
  1283.     }
  1284.     catch(const std::out_of_range &e){
  1285.         return nullptr;
  1286.     }
  1287. }
  1288.  
  1289. Stop* TransportCatalogue::get_stop(std::string_view stop_name) {
  1290.     if(stopname_to_stop.empty()){
  1291.         return nullptr;
  1292.     }
  1293.    
  1294.     try {
  1295.         return stopname_to_stop.at(stop_name);
  1296.     } catch(const std::out_of_range &e) {
  1297.         return nullptr;
  1298.     }
  1299. }
  1300.  
  1301. std::unordered_set<const Stop*> TransportCatalogue::get_uniq_stops(Bus* bus) {
  1302.     std::unordered_set<const Stop*> unique_stops;
  1303.    
  1304.     unique_stops.insert(bus->stops.begin(), bus->stops.end());
  1305.    
  1306.     return unique_stops;
  1307. }
  1308.  
  1309. double TransportCatalogue::get_length(Bus* bus) {
  1310.     return transform_reduce(next(bus->stops.begin()),
  1311.                             bus->stops.end(),
  1312.                             bus->stops.begin(),
  1313.                             0.0,
  1314.                             std::plus<>{},
  1315.                             [](const Stop* lhs, const Stop* rhs) {
  1316.                                 return detail::geo::compute_distance({(*lhs).latitude,
  1317.                                                         (*lhs).longitude}, {(*rhs).latitude,
  1318.                                                                               (*rhs).longitude});
  1319.                             });
  1320. }
  1321.  
  1322. std::unordered_set<const Bus*> TransportCatalogue::stop_get_uniq_buses(Stop* stop){    
  1323.     std::unordered_set<const Bus*> unique_stops;    
  1324.      
  1325.     unique_stops.insert(stop->buses.begin(), stop->buses.end());  
  1326.    
  1327.     return unique_stops;
  1328. }
  1329.  
  1330. size_t TransportCatalogue::get_distance_stop(const Stop* begin, const Stop* finish) {
  1331.     if(distance_to_stop.empty()){
  1332.         return 0;
  1333.     }
  1334.    
  1335.     try {
  1336.        
  1337.         auto dist_pair = std::make_pair(begin, finish);
  1338.         return distance_to_stop.at(dist_pair);
  1339.        
  1340.     } catch(const std::out_of_range &e) {
  1341.        
  1342.         try {
  1343.             auto dist_pair = std::make_pair(finish, begin);
  1344.             return distance_to_stop.at(dist_pair);
  1345.         } catch(const std::out_of_range &e) {
  1346.             return 0;    
  1347.         }
  1348.        
  1349.     }
  1350. }
  1351.  
  1352. size_t TransportCatalogue::get_distance_to_bus(Bus* bus) {
  1353.     size_t distance = 0;
  1354.     auto stops_size = bus->stops.size() - 1;
  1355.     for (int i = 0; i < stops_size; i++) {
  1356.         distance += get_distance_stop(bus->stops[i], bus->stops[i+1]);
  1357.     }
  1358.     return distance;
  1359. }
  1360.    
  1361. }//end namespace transport_catalogue
Advertisement
Add Comment
Please, Sign In to add comment