无法在 c++ 中为容器类获取插入和附加函数以正常工作

Can't get insert and attach functions to work properly for a container class in c++

本文关键字:函数 常工作 工作 c++ 插入 获取 容器类      更新时间:2023-10-16

我正在尝试通过使用实现文件中的插入和附加函数排列它们来将数字存储在我的驱动程序类中。插入函数应该将数字向左或较小的位置移动,并附加移动到数据数组中的右侧或更高位置。这是实现之一:

#include "Lab1A.h"
#include <iostream>
#include <cassert>
#include <algorithm>
sequence::sequence() {
    used = 0;
    current_index = 0;
}
// MUTATOR MEMBER FUNCTIONS 
//Postcondition: The first item in the sequence becomes the current item
void sequence::start() {
    current_index = 0;
    //Precondition: is_item returns true.
    //Postcondition: If the current item was already the last item in the
    //sequence, then there is no longer any current item. Otherwise, the new
    //current item is the item immediately after the original current item.
}
void sequence::advance() {
    if (is_item()) {
        current_index++;
    }
}
//Precondition: size( ) < CAPACITY.
//Postcondition: A new copy of entry has been inserted in the sequence
//before the current item. If there was no current item, then the new entry 
//has been inserted at the front of the sequence (position 0). In either      //case, the newly inserted item is now the current item of the sequence.
void sequence::insert(const value_type& entry) {
    if (size() < CAPACITY) {
        data[used] = data[used - 1];
        data[used] = entry;
        data[current_index] = entry;
        used++;
    }
    if (is_item() == false) {
        data[used] = entry;
        data[used] = data[used + 1];
    }
}
//Precondition: size( ) < CAPACITY.
//Postcondition: A new copy of entry has been inserted in the sequence //after the current item. If there was no current item, then the new entry //has been attached to the end of the sequence. In either case, the newly
//inserted item is now the current item of the sequence.
void sequence::attach(const value_type& entry) {
    if (size() < CAPACITY) {
        data[used] = data[used + 1];
        data[used] = entry;
        data[current_index] = entry;
        used++;
    }
    if (is_item() == false) {
        data[used] = entry;
        data[used] = data[used + 1];
    }
}
//Precondition: is_item returns true.
//Postcondition: The current item has been removed from the sequence, and //the item after this (if there is one) is now the new current item.
void sequence::remove_current() {
    int i;
    if (is_item()) {
        current_index--;
        data[i] = data[current_index];
    }
}
// ACCESSOR MEMBER FUNCTIONS
//Postcondition: The value returned is the number of items in the         
//sequence.
int sequence::size() const {
    return used;
}
//Postcondition: A true return value indicates that there is a valid
//"current" item that may be retrieved by invoking the current
//member function below. A false return value indicates that
//there is no valid current item.
bool sequence::is_item() const {
    return (current_index < used);
}
//Precondition: is_item( ) returns true.
//Postcondition: The item returned is the current item in the sequence.
sequence::value_type sequence::current() const {
    return data[current_index];
}
void sequence::print() {
    for (int j = 0; j < used; j++) {
        cout << data[j] << " ";
    }
}

驱动程序文件:

#include <iostream>
#include <cstdlib>  
#include "Lab1Aimplementation.cpp"
using namespace std;
int main()
{
    sequence numbers;
    numbers.insert(21);
    numbers.attach(33);
    numbers.insert(22);
    numbers.print();
    return 0;
}

我正在尝试获取此输出:21 22 33相反,我得到:22 33 22


可能将sequence声明为 OP 没有附加:

class sequence
{
    using index_type = int;
    using value_type = size_t;

    static const index_type CAPACITY = 1024;
    value_type data[CAPACITY];
    index_type used;
    index_type current_index;
public:
    sequence();
    void start();
    void advance();
    void insert(const value_type& entry);
    void attach(const value_type& entry);
    void remove_current();
    int size() const;
    bool is_item() const;
    value_type current() const;
    void print();
};

我在这里使用这些假设:

  1. current_index可以用迭代器表示;当没有可用的元素时,它指向 past-the-end。
  2. insert应该在当前项目之前插入,attach应该在当前项目之后插入。
  3. 根据预期结果(21 22 33)判断,这两种插入方法都是这样的,在被调用后,当前项目总是引用新插入的项目。

也就是说,如果你只是环绕一个列表,每个函数基本上都是一行,你只需要知道列表类是这样的。奖励:O(1) 插入和移除,几乎消除了容量限制。
OP 将current_index重置为 0,因此可以合理地假设它可以指向数组中的任意位置。因此,仅通过交换元素无法实现插入,您需要移动整个数据块。在这里试试这个。

#include <iostream>
#include <sstream>
#include <list>
#include <cassert>
template <typename T>
class sequence
{
private:
    std::list<T> _l;
    typename std::list<T>::iterator _i;
public:
    using value_type = T;
    using size_type = typename std::list<T>::size_type;
    size_type size() const {
        return _l.size();
    }
    T current() const {
        assert(is_current_valid());
        return *_i;
    }
    size_type current_index() const {
        return _i - _l.begin();
    }
    void increase_current() {
        if (is_current_valid()) {
            ++_i;
        }
    }
    void decrease_current() {
        if (_i != _l.begin()) {
            --_i;
        }
    }
    void reset_current() {
        _i = _l.begin();
    }
    bool is_current_valid() const {
        // "is_item"
        return _i != _l.end();
    }
    void remove_current() {
        assert(is_current_valid());
        // _i takes the next current element, eventually end()
        _i = _l.erase(_i);
    }
    void insert_before(const value_type &entry) {
        // _i is always the newly inserted element
        _i = _l.insert(_i, entry);
    }
    void insert_after(const value_type &entry) {
        // _i is always the newly inserted element
        assert(is_current_valid());
        _i = _l.insert(++_i, entry);
    }
    friend std::ostream &operator<<(std::ostream &os, sequence const &s) {
        for (auto it = s._l.begin(); it != s._l.end(); ++it) {
            if (it != s._l.begin()) {
                os << " " << *it;
            } else {
                os << *it;
            }
        }
        return os;
    }
    sequence() : _l(), _i(_l.end()) {}
};
int main() {
    sequence<std::size_t> numbers;
    numbers.insert_before(21); // insert 21, then points to 21
    numbers.insert_after(33);  // 33 after 21, then points to 33
    numbers.insert_before(22); // 22 before 21, then points to 22
    std::cout << numbers << std::endl;
    // Programmatically check if the result is the requested one
    const std::string expected = "21 22 33";
    std::stringstream output;
    output << numbers;
    if (output.str() != expected) {
        std::cerr << "Error!" << std::endl;
        return 1;
    }
    return 0;
}

在 http://www.cplusplus.com/forum/beginner/141458/找到了答案。这段代码有效,但是我不明白我猜什么是向后循环背后的逻辑。

 void sequence::attach(const value_type& entry) {// value_type is the declared typedef double data
   int i;
    if(!is_item()) // is_item checks if there's any number in the array 
        current_index = used - 1;  // used keeps track of how many numbers are stored
    for (i = used; i > current_index; --i)
       data[i]=data[i-1];
    data[current_index+1] = entry;
    ++current_index;
      ++used;
      } 

void sequence::insert(const value_type& entry){
   int i;
     if(!is_item()) 
        current_index = used; 
    for (i = used; i > current_index; --i)
       data[i]=data[i-1];
    data[current_index] = entry;
    ++current_index;
      ++used;


}