Computer >> 컴퓨터 >  >> 프로그램 작성 >> C++

C++의 범위 모듈

<시간/>

범위 모듈이 필요하다고 가정합니다. 이것은 숫자의 범위를 추적하는 모듈입니다. 우리의 임무는 다음 인터페이스를 효율적인 방식으로 설계하고 구현하는 것입니다.

  • addRange(왼쪽, 오른쪽). 이것은 반개방 간격[왼쪽, 오른쪽)이 되어 해당 간격의 모든 실수를 추적합니다. 이제 현재 추적되는 숫자와 부분적으로 겹치는 간격을 추가하면 간격에 아직 추적되지 않은 숫자가 추가되어야 합니다.
  • queryRange(왼쪽, 오른쪽) . 간격 [왼쪽, 오른쪽)의 모든 실수가 현재 추적 중이면 true를 반환합니다.
  • removeRange(left, right), [left, right) 구간에서 현재 추적 중인 모든 실수 추적을 중지합니다.

이 문제를 해결하기 위해 다음 단계를 따릅니다. −

  • 하나의 지도 정의
  • addRange() 함수를 정의하면 왼쪽, 오른쪽,
  • removeRange(왼쪽, 오른쪽)
  • m[왼쪽] :=오른쪽
  • it :=왼쪽이 m 단위로 존재하는 위치
  • m의 첫 번째 요소와 같지 않고 이전의 두 번째 값이 왼쪽과 같으면 -
    • (1씩 감소)
    • 두 번째 :=맞아
    • m에서 왼쪽 삭제
  • m의 마지막 요소의 이전 요소와 같지 않고 다음 요소의 첫 번째 요소가 오른쪽 요소와 같으면 -
    • 두 번째:=next(it)의 두 번째
    • m에서 다음(it) 삭제
  • queryRange() 함수를 정의하면 왼쪽, 오른쪽,
  • it :=m의 하위 부분의 위치는 모두 왼쪽보다 작은 값입니다.
  • m이 비어 있거나 m의 첫 번째 요소와 같으면 -
    • 거짓 반환
  • (1씩 감소)
  • 두 번째 경우 true를 반환>=오른쪽
  • removeRange() 함수를 정의하면 왼쪽, 오른쪽,
  • m이 비어 있으면 -
    • 반환
  • it :=m의 하위 부분의 위치는 모두 왼쪽보다 높은 값입니다.
  • m의 첫 번째 요소와 같지 않으면 -
    • (1씩 감소)
  • 배열 정의 v
  • 동안(m의 마지막 요소와 같지 않고 첫 번째 요소가
  • 첫 번째 <왼쪽 및 두 번째> 왼쪽이면 -
    • temp :=두 번째
    • 두 번째 :=왼쪽
    • temp> 맞으면 m[right] :=temp
  • 그렇지 않으면 처음에>=왼쪽일 때, 그 다음 −
    • v 끝에 첫 번째 삽입
    • 두 번째 경우> 맞으면 -
      • m[right] :=두 번째
  • (1씩 증가)
  • 초기화 i의 경우:=0, i
  • m에서 v[i] 삭제
  • 이해를 돕기 위해 다음 구현을 살펴보겠습니다. −

    예시

    #include <bits/stdc++.h>
    using namespace std;
    class RangeModule {
    public:
       map <int, int> m;
       RangeModule() {
       }
       void addRange(int left, int right) {
          removeRange(left, right);
          m[left] = right;
          map <int, int> :: iterator it = m.find(left);
          if(it != m.begin() && prev(it)->second == left){
             it--;
             it->second = right;
             m.erase(left);
          }
          if(it != prev(m.end()) && next(it)->first == right){
             it->second = next(it)->second;
             m.erase(next(it));
          }
       }
       bool queryRange(int left, int right) {
          map <int, int> :: iterator it = m.upper_bound(left);
          if(m.empty() || it == m.begin())return false;
          it--;
          return it->second >= right;
       }
       void removeRange(int left, int right) {
          if(m.empty())return;
          map <int, int> :: iterator it = m.lower_bound(left);
          if(it != m.begin())it--;
          vector <int> v;
          while(it != m.end() && it->first < right){
             if(it->first < left && it->second > left){
                int temp = it->second;
                it->second = left;
                if(temp > right){
                   m[right] = temp;
                }
             }else if(it->first >= left){
                v.push_back(it->first);
                if(it->second > right){
                   m[right] = it->second;
                }
             }
             it++;
          }
          for(int i = 0; i < v.size(); i++){
             m.erase(v[i]);
          }
       }
    };
    main(){
       RangeModule ob;
       ob.addRange(10,20);
       ob.removeRange(14,16);
       cout << (ob.queryRange(10,14)) << endl;
       cout << (ob.queryRange(13,15)) << endl;
       cout << (ob.queryRange(16,17));
    }

    입력

    Add range (10,20)
    Remove Range (14,16)
    Check ranges (10,14), (13,15), (16,17)

    출력

    1
    0
    1