patrikey

main.cpp

May 31st, 2023 (edited)
908
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.67 KB | Source Code | 0 0
  1. #include <algorithm>
  2. #include <cassert>
  3. #include <iostream>
  4. #include <string>
  5. #include <sstream>
  6. #include <string_view>
  7. #include <vector>
  8.  
  9. using namespace std;
  10.  
  11. class Domain {
  12. public:
  13.     Domain(string name) : name_(move(name)) {
  14.         name_.insert(0, 1, '.');
  15.     }
  16.     bool operator==(const Domain& other) const {
  17.         return name_ == other.name_;
  18.     }
  19.     bool operator<(const Domain& other) const {
  20.         return lexicographical_compare(name_.rbegin(), name_.rend(), other.name_.rbegin(), other.name_.rend());
  21.     }
  22.     bool IsSubdomain(const Domain& root) const {
  23.         string reverse_domain = string{ name_.rbegin(), name_.rend() };
  24.         string reverse_root = string{ root.name_.rbegin(), root.name_.rend() };
  25.         if (reverse_domain.find(reverse_root) == 0) {
  26.             return true;
  27.         }
  28.         return false;
  29.     }
  30.     void SetName(string name) {
  31.         name_ = move(name);
  32.     }
  33. private:
  34.     string name_;
  35. };
  36.  
  37. template <typename InputIt>
  38. class DomainChecker {
  39. public:
  40.     DomainChecker(InputIt begin, InputIt end) : sorted_domains{begin, end} {
  41.         sort(sorted_domains.begin(), sorted_domains.end());
  42.     }
  43.     bool IsForbidden(const Domain& domain) {
  44.         auto it = upper_bound(sorted_domains.begin(), sorted_domains.end(), domain);
  45.         if (it == sorted_domains.begin()) {
  46.             return false;
  47.         }
  48.         return domain.IsSubdomain(*prev(it));
  49.     }
  50. private:
  51.     vector<Domain> sorted_domains;
  52. };
  53.  
  54. vector<Domain> ReadDomains(istream& in, int count) {
  55.     vector<Domain> domains;
  56.     for (int i = 0; i < count; ++i) {
  57.         string domain_name;
  58.         getline(in, domain_name);
  59.         domains.push_back(Domain(domain_name));
  60.     }
  61.     return domains;
  62. }
  63.  
  64.  
  65. template <typename Number>
  66. Number ReadNumberOnLine(istream& input) {
  67.     string line;
  68.     getline(input, line);
  69.  
  70.     Number num;
  71.     std::istringstream(line) >> num;
  72.  
  73.     return num;
  74. }
  75.  
  76. void TestIsSubdomain() {
  77.     Domain d{ "abc.com.ru" };
  78.     assert(d.IsSubdomain(Domain{ "ru" }));
  79.     assert(!d.IsSubdomain(Domain{ ".om" }));
  80.     assert(d.IsSubdomain(Domain{ "com.ru" }));
  81.     assert(!d.IsSubdomain(Domain{ "xyz.abc.com.ru" }));
  82.     assert(d.IsSubdomain(Domain{ "abc.com.ru" }));
  83. }
  84.  
  85. int main() {
  86.     TestIsSubdomain();
  87.  
  88.     const std::vector<Domain> forbidden_domains = ReadDomains(cin, ReadNumberOnLine<size_t>(cin));
  89.     DomainChecker checker(forbidden_domains.begin(), forbidden_domains.end());
  90.  
  91.     const std::vector<Domain> test_domains = ReadDomains(cin, ReadNumberOnLine<size_t>(cin));
  92.     for (const Domain& domain : test_domains) {
  93.         cout << (checker.IsForbidden(domain) ? "Bad"sv : "Good"sv) << endl;
  94.     }
  95. }
Advertisement
Add Comment
Please, Sign In to add comment