2017-05-02 15 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; 
    } 
}; 

私は次のように消去方法を実行して実行します。

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

私は、次を得る:

-842150451 
-842150451 
25 
-842150451 

私はなぜこれが起こって本当にでしれる見当がつかないヘルプを使用してください。おかげさまで

newElems[*iter] = elems[*iter];

答えて

1

erase()コードは新しい配列を作成します。しかし、返されたイテレーターは引き続き古い配列を指しています。あなたが本当に新しい配列を割り当てることを意味する場合は、古い配列をINGの右delete[]

pos = newElems + (pos - elems); 

を使用して、例えば、その結果にポイントを作成する必要があります。

Vectorには容量があるので、実際には末尾の要素を1つ前の位置に移動してend()を調整するだけで済みます。これは要素をコピーする作業を避け、新しいメモリを完全に割り当てることを避けます。その場合、返されたposは変更されず、end()だけが変更されます。

要素を移動するための明白な方法はstd::copy()を使用することです:

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

対応するループは、あまりにも、書きやすいです:

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

は意味があります。 'for'ループで要素を正しく変更していないように見えます。特に、私は 'elems [i]'にアクセスし、それを 'elems [i + 1]'に置き換える方法については、繰り返しのためのイテレータを使用するだけではわかりません。 – dezdichado

+0

私はちょうどコードが今働いている。ありがとう! – dezdichado

2

*iter、ないインデックスあります。

+0

その配列を反復処理する正しい方法は何ですか'elems []'? '(int)* iter'をキャストしようとしましたが、うまく動作しませんでした。 – dezdichado

関連する問題