for (int i = peekIndex; i < pdp->size(); i++)
{
string x = pdp->peek();
if (x.at(0) == 's')
{
out << pdp->peek() << endl;
pdp->moveForward();
}
else
{
pdp->moveForward();
}
}
The error I get is
terminate called after throwing and instance of
std::out_of_range
what(): basic_string::at()
Abort
The peek
method returns a string in the position of the peekIndex
.
The moveFowrard
method increments the peekIndex
.
pdp
is a vector
of size 100. I am supposed to peek and print only words that start with 's' that have been pushed to the <vector>
. I am basically done but this part is proving somewhat difficult.
Thanks
#include<iostream>
#include<vector>
#include<string>
using namespace std;
class StringDeque {
protected:
vector<string>* elements;
int frontItem; //CLASS INV: indexes item with least index
int rearSpace; //CLASS INV: indexes space after item with greatest index
int upperBound; //For array[0..n-1] this is "n" not "n-1".
public:
StringDeque(int guaranteedCapacity):
elements (new vector<string>( 2*guaranteedCapacity))
frontItem (guaranteedCapacity),
rearSpace ( guaranteedCapacity),
upperBound ( 2*guaranteedCapacity)
{}
proteted:
virtual bool isEmpty() const { return frontItem == rearSpace; }
virtual bool isFull() const { return rearSpace == upperBound || frontItem == 0; }
virtual int size() const { return rearSpace - frontItem; }
virtual string popRear() {
if (isEmpty()) {
cerr<< "Later we'll define and throw an EmptyQException"<< endl;
return "";
} else {
return elements->at(--rearSpace);
}
}
virtual string popFront() {
if (isEmpty()) {
cerr<<"Later we'll define and throw an EmptyQException"<<endl;
return "";
} else {
return elements->at(frontItem++);
}
}
/** Directions include similarly testing for "full" in the C++ code.
*/
virtual void pushFront(string newItem) {
elements->at(--frontItem)= newItem;
}
virtual void pushRear(string newItem) {
elements->at(rearSpace++) = newItem;
}
virtual string toString() {
string out = "";
for (int i = frontItem; i < rearSpace; i++) {
out += elements->at(i) + " ";
}
return out;
}
};
class PeekDeque : public StringDeque {
private:
int peekIndex;
public:
PeekDeque(int guaranteedCapacity):
StringDeque(guaranteedCapacity),
peekIndex(guaranteedCapacity/2)
{}
virtual void moveFrontward() {
if (peekIndex == upperBound) {
cerr<<"Cannot move past total capacity"<<endl;
} else{
elements->at(peekIndex ++);
}
}
virtual void moveRearward () {
if (peekIndex == -1) {
cerr<<"Cannot move below total capacity"<<endl;
} else{
elements ->at( peekIndex--);
}
}
virtual string popFront() {
cerr<<"Attempt to pop from empty PeekDeque"<<endl;
}
virtual string popRear() {
cerr<<"Attempt to pop from empty PeekDeque"<<endl;
}
virtual string peek() {
if (isEmpty()) {
cerr<<"Cannot peek an Empty index"<<endl;
return "";
} else {
return elements->at(peekIndex + 1);
}
}
virtual string toString() {
string out = "";
for (int i = frontItem; i < rearSpace; i++) {
out += elements->at(i) + " ";
}
return out;
}
};
int main(){
PeekDeque* pdp = new PeekDeque(101);
pdp->pushFront("oh");
pdp->pushFront("say");
pdp->pushFront("can");
pdp->pushFront("you");
pdp->pushFront("see");
pdp->pushRear("any");
pdp->pushRear("bad bugs");
pdp->pushRear("on");
pdp->pushRear("me?");
for(int i = peekIndex; i<pdp->size(); i++){
string x =
if(x.at(0)=='s'){
cout<<pdp->peek()<<endl;
pdp->moveForward(); }
else{
pdp->moveForward();
}
}
}
Here's how your container looks like after initial pushes:
0 202
| ... | ... | ... | ... |
^ ^ ^
| | rearSpace
| peekIndex
frontItem
Now, size()
returns rearSpace - frontItem
, but iteration starts from peekIndex
and thus goes beyond rearSpace
index, peeking uninitialized (empty) strings.
That's certainly an approximate answer, since your work with indices is a mess. Please be really careful and think it through.