2017-05-02 18 views
0

사용자 정의 Vector 클래스를 구현하려고하는데 지우기 메소드 구현에 매달렸다. 이 메서드는 제거 할 요소를 가리키는 반복자를 사용하고 제거 된 요소 다음에 반복자를 반환해야합니다. 여기에 지우기 메서드를 구현하려는 시도가 있습니다.이터레이터 사용자 정의 구현 지우기 C++

iterator erase(iterator pos) { 
      // TODO: Implement this function. 
      if (pos == end()) { 
       return end(); 
      } 
      T* newElems = new T[cap]; 
      for (iterator iter = begin(); iter != pos; iter++) { 
       newElems[*iter] = elems[*iter]; 
      } 
      for (iterator iter = pos + 1; iter != end()-1; iter++) { 
       newElems[*iter] = elems[*iter+1];  
      } 
      delete[] elems; 
      elems = newElems; 
      return pos; 
     } 

Vector 클래스는 다음과 같이 정의되며 다른 모든 기본 메서드와 함수를 구현했습니다. 나는 실행을 다음과 같은 방법으로 지우기 방법 실행하면

#include <cstdio> 
#include <iostream> 
#include <stdexcept> 

/** 
* @brief A templated sequence container that encapsulates dynamic size arrays. 
*/ 
template<typename T> 
class Vector { 
private: 
    T *elems; // an array of the elements stored in the Vector 
    std::size_t cap; // the current capacity of the array 
    std::size_t length; // the number of elements inside the Vector 
    static const std::size_t initialCapacity = 2; 
    /* If you want to add methods, add them below this line */ 

    /* If you want to add methods, add them above this line */ 

public: 
    /** 
    * @brief Default Constructor. 
    */ 
    Vector() { 
     // TODO: Implement this function. 
     length = 0; 
     cap = initialCapacity; 
     elems = new T[cap]; 

    } 

    /** 
    * @brief Copy Constructor. 
    * @param other The vector from which we should copy from. 
    */ 
    Vector(const Vector &other) { 
     // TODO: Implement this function. 
     elems = new T[other.cap]; 
     cap = other.cap; 
     length = other.length; 
     for (int i = 0; i < other.length; i++) { 
      elems[i] = other.elems[i]; 
     } 
    } 

    /** 
    * @brief Copy Assignment Operator. 
    * @param other The vector on the RHS of the assignment. 
    * @return A reference to the vector on the LHS. 
    */ 
    Vector &operator=(const Vector &other) { 
     // TODO: Implement this function. 
     this->elems = &other.elems; 
     this->cap =other.cap; 
     this->length = other.length; 
    } 

    /** 
    * @brief Destructor. 
    */ 
    ~Vector() { 
     // TODO: Implement this function. 
     delete [] elems; 
    } 

    typedef T* iterator; 
    typedef const T* constIterator; 

    /** 
    * @brief Begin iterator. 
    * @return An iterator to the first element. 
    */ 
    iterator begin() { 
     // TODO: Implement this function. 
     return elems; 
    } 

    /** 
    * @brief End iterator. 
    * @return An iterator to one past the last element. 
    */ 
    iterator end() { 
     // TODO: Implement this function. 
     return elems + length; 
    } 

    /** 
    * @brief Const begin iterator. This is a const overloaded function. 
    * @return A const iterator to the first element. 
    */ 
    constIterator begin() const { 
     // TODO: Implement this function. 
     return constIterator(elems); 
    } 

    /** 
    * @brief Const end iterator. This is a const overloaded function. 
    * @return A const iterator to one past the last element. 
    */ 
    constIterator end() const { 
     // TODO: Implement this function. 
     return constIterator(elems+size()); 
    } 

    /** 
    * @brief Gets the number of elements that the container has currently allocated space for. 
    * @return The number of elements that can be held in currently allocated storage. 
    */ 
    std::size_t capacity() const { 
     // TODO: Implement this function. 
     return this->cap; 
    } 

    /** 
    * @brief Gets the number of elements. 
    * @return The number of elements in the container. 
    */ 
    std::size_t size() const { 
     // TODO: Implement this function. 
     return this->length; 
    } 

    /** 
    * @brief Adds an element to the end. 
    *  If there is no space to add an element, then the capacity of the vector is doubled.. 
    * @param elem The element to be added. 
    */ 
    void pushBack(T elem) { 
     // TODO: Implement this function. 
     if (size() >= capacity()) { 
      reserve(2*capacity()); 
     } 
     elems[size()] = elem; 
     length++; 
    } 

    /** 
    * @brief Removes the last element of the container. 
    *  The capacity of the vector is unchanged. 
    *  If there are no elements in the container, then do nothing. 
    */ 
    void popBack() { 
     // TODO: Implement this function. 
     if (size()!=0) { 
      --length; 
     } 
    } 

    /** 
    * @brief Increases the capacity of the container to a value greater or equal to new_cap. 
    *  If new_cap is greater than the current capacity(), new storage is allocated, 
    *  otherwise the method does nothing. 
    * @param new_cap new capacity of the container. 
    */ 
    void reserve(std::size_t new_cap) { 
     // TODO: Implement this function. 
     T* newElems = new T[new_cap]; 
     int newSize = new_cap < length ? new_cap : length; 
     for (int i = 0; i < newSize; i++) { 
      newElems[i] = elems[i]; 
     } 
     cap = new_cap; 
     delete[] elems; 
     elems = newElems; 
    } 

    /** 
    * @brief Overloaded array subscripting operator. 
    * @param pos The position of the element to access. 
    * @return A reference to the element at specified location pos. 
    *   No bounds checking is performed. 
    */ 
    T &operator[](std::size_t pos) { 
     // TODO: Implement this function. 
     return elems[pos]; 

    } 

    /** 
    * @brief Const overload of the overloaded array subscripting operator. 
    * @param pos The position of the element to access. 
    * @return A const reference to the element at specified location pos. 
    *   No bounds checking is performed. 
    */ 
    const T &operator[](std::size_t pos) const { 
     // TODO: Implement this function. 
     return elems[pos]; 
    } 

    /** 
    * @brief Access specified element with bounds checking. 
    * @param pos The position of the element to access. 
    * @return A reference to the element at specified location pos, with bounds checking. 
    * @throw std::out_of_range if pos >= the size of the vector. 
    */ 
    T &at(std::size_t pos) { 
     // TODO: Implement this function. 
     if (pos >= size()) { 
      throw std::out_of_range; 
     } 
     return elems[pos]; 
    } 

    /** 
    * @brief Const overload to access specified element with bounds checking. 
    * @param pos The position of the element to access. 
    * @return A const reference to the element at specified location pos, with bounds checking. 
    * @throw std::out_of_range if pos >= the size of the vector. 
    */ 
    const T &at(std::size_t pos) const { 
     // TODO: Implement this function. 
     if (pos>=size()) { 
      throw std::out_of_range; 
     } 
     return const elems[pos]; 
    } 

    /** 
    * @brief Checks whether the container is empty. 
    * @return true if the container is empty, false otherwise. 
    */ 
    bool empty() const { 
     // TODO: Implement this function. 
     if (size()==0) { 
      return true; 
     } 
     return false; 
    } 

    /** 
    * @brief Removes all elements from the container. 
    *  Leaves the capacity of the vector unchanged. 
    */ 
    void clear() { 
     // TODO: Implement this function. 
     while (!empty()) { 
      this->popBack(); 
     } 
    } 

    /** 
    * @brief Erases an element at pos. 
    * @param pos Iterator to the element to remove. 
    * @return Iterator following the last removed element. 
    *   If the iterator pos refers to the last element, the end() iterator is returned. 
    */ 
    iterator erase(iterator pos) { 
     // TODO: Implement this function. 
     if (pos == end()) { 
      return end(); 
     } 
     T* newElems = new T[cap]; 
     for (iterator iter = begin(); iter != pos; iter++) { 
      newElems[*iter] = elems[*iter]; 
     } 
     for (iterator iter = pos + 1; iter != end()-1; iter++) { 
      newElems[*iter] = elems[*iter+1];  
     } 
     delete[] elems; 
     elems = newElems; 
     return pos; 
    } 
}; 

는 :

-842150451 
-842150451 
25 
-842150451 

나는이 정말 수 일어나고있는 이유를 전혀 몰라 :

// a2 = {2,3,25,42} currently   
    Vector<int>::iterator it = a2.begin(); 
    a2.erase(it+1); 
    print(a2); 

을 나는 다음과 같은 수 도움을 받으십시오. 감사합니다. .

답변

1

erase() 코드는 새 배열을 만듭니다. 그러나 반환 된 이터레이터는 여전히 이전 배열을 가리 킵니다. 당신이 정말로 새로운 배열을 할당 할 말은 경우에 당신은 기존의 배열을 보내고 바로 delete[] 전에

pos = newElems + (pos - elems); 

를 사용하여, 예를 들면, 그에 결과 점을 확인해야합니다.

Vector에는 용량이 있으므로 실제로 후행 요소를 한 위치 앞으로 이동하고 end()을 조정하면됩니다. 따라서 요소를 복사하는 작업을 피하고 새 메모리를 완전히 할당하지 않아도됩니다. 이 경우 반환 된 pos은 변경되지 않고 그대로 유지됩니다. end() 만 변경됩니다. 도

std::copy(pos + 1, end(), pos); 

해당 루프를 작성하기 쉽습니다 :

요소를 이동하는 확실한 방법은 std::copy()을 사용하는 것입니다

for (++pos; pos != end(); ++pos) { 
    pos[-1] = pos; 
} 
+0

이 좋습니다. 하지만 'for' 루프에서 요소를 올바르게 수정하지 않는 것 같습니다. 특히, 나는 elems [i]에 접근하는 방법을 잘 모르고 반복자 for loop만을 사용하여 elems [i + 1]로 바꾼다. – dezdichado

+0

방금 ​​코드가 작동했습니다. 감사! – dezdichado

2

newElems[*iter] = elems[*iter];에서 *iter 아닌 인덱스이다.

+0

다음 배열을 반복하는 올바른 방법은 무엇입니까 'elems []'? 나는'int (int) * iter'를 캐스팅하려고 시도했지만 작동하지 않았습니다. – dezdichado