Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <queue>
- #include <sstream>
- using namespace std;
- template<class T>
- class ICircularBoundedQueue {
- public:
- virtual void offer(T value) = 0; // insert an element to the rear of the queue
- // overwrite the oldest elements
- // when the queue is full
- virtual T poll() = 0; // remove an element from the front of the queue
- virtual T peek() = 0; // look at the element at the front of the queue
- // (without removing it)
- virtual void flush() = 0; // remove all elements from the queue
- virtual bool isEmpty() = 0; // is the queue empty?
- virtual bool isFull() = 0; // is the queue full?
- virtual int size() = 0; // number of elements
- virtual int capacity() = 0; // maximum capacity
- };
- template<class T>
- class ArrayCircularBoundedQueue : public virtual ICircularBoundedQueue<T>
- {
- private:
- const size_t CAPACITY;
- T* arr_;
- T default_value_;
- int index_front_;
- int index_rear_;
- public:
- explicit ArrayCircularBoundedQueue(size_t capacity, T default_value) :CAPACITY(capacity), arr_(new T[CAPACITY]), default_value_(default_value), index_front_(-1),
- index_rear_(-1)
- {}
- void offer(T value) override
- {
- if (index_front_ == -1 && index_rear_ == -1)
- {
- arr_[0] = value;
- index_front_ = 0;
- index_rear_ = 0;
- }
- else
- {
- index_rear_ = (index_rear_ + 1) % CAPACITY;
- if (index_rear_ == index_front_)
- index_front_ = (index_front_ + 1) % CAPACITY;
- arr_[index_rear_] = value;
- }
- }
- T poll() override
- {
- if (index_front_ == -1 && index_rear_ == -1)
- return default_value_;
- T val = arr_[index_front_];
- if (index_front_ == index_rear_)
- {
- index_front_ = -1;
- index_rear_ = -1;
- }
- else index_front_ = (index_front_ + 1) % CAPACITY;
- return val;
- }
- T peek() override
- {
- if (index_front_ == -1 && index_rear_ == -1)
- return default_value_;
- return arr_[index_front_];
- }
- void flush() override
- {
- index_front_ = -1;
- index_rear_ = -1;
- }
- bool isEmpty() override
- {
- return (index_front_ == -1 && index_rear_ == -1);
- }
- bool isFull() override
- {
- return abs(index_front_ - index_rear_) == (CAPACITY - 1);
- }
- int size() override
- {
- if (index_front_ == -1 && index_rear_ == -1)
- return 0;
- if (index_front_ <= index_rear_)
- return index_rear_ - index_front_ + 1;
- return CAPACITY - index_front_ + index_rear_ + 1;
- }
- int capacity() override
- {
- return CAPACITY;
- }
- ArrayCircularBoundedQueue& operator=(ArrayCircularBoundedQueue queue) noexcept
- {
- if (this == &queue)
- return *this;
- copy(queue.arr_, queue.arr_ + queue.capacity(), this->arr_);
- this->index_front_ = queue.index_front_;
- this->index_rear_ = queue.index_rear_;
- this->default_value_ = queue.default_value_;
- return *this;
- }
- };
- template<class T>
- class IBoundedStack
- {
- public:
- virtual void push(T value) = 0; // push an element onto the stack
- // remove the oldest element
- // when if stack is full
- virtual T pop() = 0; // remove an element from the top of the stack
- virtual T top() = 0; // look at the element at the top of the stack
- // (without removing it)
- virtual void flush() = 0; // remove all elements from the stack
- virtual bool isEmpty() = 0; // is the stack empty?
- virtual bool isFull() = 0; // is the stack full?
- virtual int size() = 0; // number of elements
- virtual int capacity() = 0; // maximum capacity
- };
- template<class T>
- class BoundedStack :public IBoundedStack<T>
- {
- private:
- const size_t CAPACITY;
- const T DEFAULT_VALUE;
- ArrayCircularBoundedQueue<T> main_queue_;
- ArrayCircularBoundedQueue<T> duplicate_queue_;
- public:
- BoundedStack(size_t capacity, T default_value) :CAPACITY(capacity), DEFAULT_VALUE(default_value), main_queue_(CAPACITY, default_value), duplicate_queue_(CAPACITY, default_value)
- {}
- void push(T value) override
- {
- main_queue_.offer(value);
- }
- T pop() override
- {
- if (main_queue_.isEmpty())
- return DEFAULT_VALUE;
- while (main_queue_.size() > 1)
- {
- duplicate_queue_.offer(main_queue_.poll());
- }
- T returnValue = main_queue_.poll();
- main_queue_ = duplicate_queue_;
- duplicate_queue_.flush();
- return returnValue;
- }
- T top() override
- {
- T returnValue = pop();
- main_queue_.offer(returnValue);
- return returnValue;
- }
- void flush() override
- {
- main_queue_.flush();
- }
- bool isEmpty() override
- {
- return main_queue_.isEmpty();
- }
- bool isFull() override
- {
- return main_queue_.isFull();
- }
- int size() override
- {
- return main_queue_.size();
- }
- int capacity() override
- {
- return CAPACITY;
- }
- };
- template<class T>
- class ISet {
- public:
- virtual void add(T item) = 0; // add item in the set
- virtual void remove(T item) = 0; // remove an item from a set
- virtual bool contains(T item) = 0; // check if a item belongs to a set
- virtual int size() = 0; // number of elements in a set
- virtual bool isEmpty() = 0; // check if the set is empty
- };
- template<class T>
- class DoubleHashSet : public virtual ISet<T>
- {
- private:
- T* arr_;
- bool* arr_exist_;
- int size_{ 0 };
- const int CAPACITY = 1003;
- const int prime_num = 37;
- void get_hashes(const T& item, long long& hash1, long long& hash2)
- {
- auto hash_ = hash<T>();
- const string string_item = (string) item;
- hash1 = abs((int)(hash_(item))) % CAPACITY;
- hash2 = abs(prime_num - hash1 % prime_num) % (CAPACITY - 2);
- }
- bool findIndex(T item, int* index = nullptr)
- {
- long long hash1;
- long long hash2;;
- int hash_code;
- get_hashes(item, hash1, hash2);
- for (int j = 0; j < CAPACITY; j++)
- {
- hash_code = (hash1 + j * hash2) % CAPACITY;
- if (arr_exist_[hash_code] != false && arr_[hash_code] == item)
- {
- if (index != nullptr)
- *index = hash_code;
- return true;
- }
- }
- return false;
- }
- public:
- DoubleHashSet()
- {
- arr_ = new T[CAPACITY];
- arr_exist_ = new bool[CAPACITY];
- for (int i = 0; i < CAPACITY; i++)
- arr_exist_[i] = false;
- }
- DoubleHashSet(const DoubleHashSet& set)
- {
- this->size_ = set.size_;
- this->arr_ = new T[CAPACITY];
- this->arr_exist_ = new bool[CAPACITY];
- std::copy(set.arr_, set.arr_ + set.CAPACITY, this->arr_);
- std::copy(set.arr_exist_, set.arr_exist_ + set.CAPACITY, this->arr_exist_);
- }
- ~DoubleHashSet()
- {
- delete[] arr_;
- delete[] arr_exist_;
- }
- void add(T item) override
- {
- if (size() == CAPACITY)
- throw overflow_error("Set is full");
- long long hash1;
- long long hash2;
- int hash_code;
- get_hashes(item, hash1, hash2);
- for (int j = 1; j < CAPACITY; j++)
- {
- hash_code = (hash1 + j * hash2) % CAPACITY;
- if (arr_exist_[hash_code] == false)
- {
- size_++;
- arr_[hash_code] = item;
- arr_exist_[hash_code] = true;
- return;
- }
- }
- }
- void remove(T item) override
- {
- long long hash1;
- long long hash2;
- int hash_code;
- get_hashes(item, hash1, hash2);
- for (int j = 1; j < CAPACITY; j++)
- {
- hash_code = (hash1 + j * hash2) % CAPACITY;
- if (arr_[hash_code] == item)
- {
- size_--;
- arr_exist_[hash_code] = false;
- return;
- }
- }
- }
- bool contains(T item) override
- {
- return findIndex(item);
- }
- int size() override
- {
- return size_;
- }
- bool isEmpty() override
- {
- return size_ == 0;
- }
- operator string() const
- {
- ostringstream ans;
- for (int i = 0; i < CAPACITY; i++)
- if (arr_exist_[i] != false)
- ans << arr_[i] << " ";
- return ans.str();
- }
- DoubleHashSet& operator= (const DoubleHashSet& set)
- {
- if (this == &set)
- return *this;
- delete[] arr_;
- delete[]arr_exist_;
- this->size_ = set.size_;
- this->arr_ = new T[CAPACITY];
- this->arr_exist_ = new bool[CAPACITY];
- std::copy(set.arr_, set.arr_ + set.CAPACITY, this->arr_);
- std::copy(set.arr_exist_, set.arr_exist_ + set.CAPACITY, this->arr_exist_);
- return *this;
- }
- };
- void parse_line(string& line, string& command, string& parameter)
- {
- const size_t space_index = line.find(' ');
- if (space_index != string::npos)
- {
- command = line.substr(0, space_index);
- parameter = line.substr(space_index + 1);
- }
- else
- {
- command = line.substr(0);
- parameter = "";
- }
- }
- int main()
- {
- int n, k;
- cin >> n >> k;
- DoubleHashSet<string> Set;
- BoundedStack<DoubleHashSet<string>> StatusSet(k, DoubleHashSet<string>());
- bool flag = true;
- string line, command, parameter;
- getline(cin, line);
- for (int i = 0; i < n; i++)
- {
- getline(cin, line);
- parse_line(line, command, parameter);
- if (command == "NEW")
- {
- string second_name = parameter;
- if (second_name[second_name.size() - 1] == '/')
- second_name = second_name.substr(0, second_name.size() - 1);
- else second_name = second_name.append("/");
- if (!(Set.contains(second_name) || Set.contains(parameter)))
- {
- Set.add(parameter);
- StatusSet.push(Set);
- }
- else cout << "ERROR: cannot execute " << command.append(" ").append(parameter).append("\n");
- }
- if (command == "REMOVE")
- {
- if (Set.contains(parameter))
- {
- Set.remove(parameter);
- StatusSet.push(Set);
- }
- else cout << "ERROR: cannot execute " << command.append(" ").append(parameter).append("\n");
- }
- if (command == "UNDO")
- {
- int undo_parameter = 1;
- if (!parameter.empty())
- undo_parameter = stoi(parameter, nullptr, 10);
- if ((!flag && (undo_parameter == StatusSet.size())) || (undo_parameter >= k) || undo_parameter > StatusSet.size())
- {
- cout << "ERROR: cannot execute " << command.append(" ").append(parameter).append("\n");
- }
- else
- {
- for (int i = 0; i < undo_parameter; i++)
- {
- StatusSet.pop();
- }
- Set = StatusSet.top();
- }
- }
- if (command == "LIST")
- {
- cout << static_cast<string>(Set) << endl;
- }
- if (flag)
- flag = !StatusSet.isFull();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement