-1

I'm trying to store the numbers in my driver class by arranging them with insert and attach functions from the implementation file. Insert function is supposed to move the number to the left or a smaller position and attach moves to the right or higher position in the data array.This is the implementation one:

#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] << " ";
    }
}

Driver file:

#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;
}

I'm trying to get this output: 21 22 33 Instead I get: 22 33 22


Possible declaration of sequence as OP didn't attach one:

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();
};
Simon Kraemer
  • 5,700
  • 1
  • 19
  • 49
codeing
  • 9
  • 1
  • 3
  • The terminology you are using is extremely confusing. What do you mean? is `sequence` just some implementation of a `list`? the semantic of `insert` is ok, but `attach` seems to be an `insert_after` operation. And `is_item` just means that your iterator points after the end of the list? – Pietro Saccardi Feb 25 '16 at 12:06
  • `i` isn't initialized in `remove_current`. Please don't ignore compiler warnings. – Simon Kraemer Feb 25 '16 at 12:10
  • Also I have no idea what `remove_current` is intended to do... – Simon Kraemer Feb 25 '16 at 12:10
  • 1
    `insert` is also pretty damaged. When inserting the first element you use `data[used] = data[used - 1];` with `used=0`... Also you override `data[used] in the next line... – Simon Kraemer Feb 25 '16 at 12:12
  • Downvoting because until the OP clarifies what he is trying to achieve, the question just raises questions about itself. – Pietro Saccardi Feb 25 '16 at 22:09
  • Not sure what you don't understand. I am trying to get insert function to move the number more to the front in the array or to the left. Vice versa with attach(move it to the end or to the right in the data array. Here's the output again in case you didn't see that I'm getting: 22 33 22 . This is what I'm going for: 21 22 33 – codeing Feb 26 '16 at 03:56
  • I don't understand the meaning of the methods and the purpose of the class. I can probably help you fixing them, but having unclear what you want to achieve, it's like being blind. This is what I think you want: a list class, in which you can select an element (the `current_item`) that acts as an insertion point, and then using `insert`, you insert *before* it, and using `attach`, you insert *after* it? – Pietro Saccardi Feb 26 '16 at 10:15
  • You got it for the most part. They are pretty much before and after functions.Also current_index is for holding the index of the current number in the array. The int used is for keeping track of the number of items currently in the sequence. All the numbers are stored in the typedef double data. – codeing Feb 26 '16 at 20:33
  • @codeing what is "typedef double data"? Look, clearly this is a programming exercise (LAB1A), and considering mistakes and terminology, I recommend to take a sheet of paper, and try out a few examples of how this is supposed to work in your mind, and keep going until it's clear. Only after that, consider asking here, *if you can formulate a specific question*; if you haven't done it yet, read http://stackoverflow.com/help/how-to-ask, http://stackoverflow.com/help/dont-ask, http://stackoverflow.com/help/mcve. – Pietro Saccardi Feb 28 '16 at 14:44
  • typedef double data is the array for storing all the numbers. I don't how else to explain or be more clear to you. The insert function has to put the number in the lower position in the array and the attach function has to put the number in the higher position. Thanks for the attempt but I found the answer. I'm going to post it. – codeing Feb 29 '16 at 02:02
  • @codeing I was confused because in the code you posted there is no `typedef` and as well no `double`-- the field `data` is defined as a plain C array of `value_type`, which is `using value_type = size_t`; `size_t` is commonly used for indices, and `index_type` is `int`, which is usually used as a "test type", so this sort of role swap made me doubt whether I had understood the question. It's good that you found a working example; I hope my answer can also be of use. – Pietro Saccardi Feb 29 '16 at 17:12

2 Answers2

0

I'm using here these assumptions:

  1. current_index can be represented by an iterator; when no element is available, it points to past-the-end.
  2. insert is supposed to insert before the current item, attach is supposed to insert after the current item.
  3. Both insertion methods, judging by the expected result (21 22 33) are such that after being called, the current item always refers to the newly inserted item.

This said, if you just wrap around a list, each function is basically a one liner, you just need to know that the list class does. Bonus: O(1) insertion and removal, capacity constraint virtually removed.
The OP resets current_index to 0, so it is reasonable to assume that it could point anywhere in the array. Therefore, it is not possible to achieve insertion just by swapping elements, you need to move a whole block of data. Try this out here.

#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;
}
Community
  • 1
  • 1
Pietro Saccardi
  • 2,602
  • 34
  • 41
0

Found the answer at http://www.cplusplus.com/forum/beginner/141458/. This code works, however I don't understand the logic behind what is I guess a backwards loop.

 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;





}
codeing
  • 9
  • 1
  • 3
  • The reason behind that backwards loop is to shift by one position right everything that follows `current_index` up to `used`, to make room for the new element you are inserting. – Pietro Saccardi Feb 29 '16 at 10:21