Practice 1 - 3
#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>
using namespace std;
int main() {
int narray[] = {435, 225, 55, 983, 100, 391, 355, 6, 26};
int size = sizeof narray / sizeof(int);
vector<int> v1(size);
v1.assign(narray, narray + size);
cout << "v1:\n";
copy(v1.begin(), v1.end(), ostream_iterator<int>(cout, " "));
cout << endl;
sort(v1.begin(), v1.end());
cout << "v1 after sort():\n";
copy(v1.begin(), v1.end(), ostream_iterator<int>(cout, " "));
cout << endl;
reverse(v1.begin(), v1.end());
cout << "v1 after reverse():\n";
copy(v1.begin(), v1.end(), ostream_iterator<int>(cout, " "));
cout << endl;
return 0;
}
Practice 4
#include <iostream>
#include <list>
#include <string>
#include <algorithm>
using namespace std;
class Cell {
int x, y;
string text;
public:
Cell(int x, int y, const string &text) : x(x), y(y) {
this->text = string(text);
}
int getX() {return x;}
int getY() {return y;}
string getText() {return text;}
void setText(string text) {this->text = string(text);}
Cell* clone() {return new Cell(x, y, text);}
};
class Sheet;
//this memento will store pointers for an old cell and a new cell
class CellMemento {
Cell* pOldCell;
Cell* pNewCell;
// make Sheet class a frind of CellMemento so that only Sheet class can
// access pOldCell/pNewCell
friend class Sheet;
public:
CellMemento(Cell* pOldCell, Cell* pNewCell) : pOldCell(pOldCell), pNewCell(pNewCell) {}
~CellMemento() {
// pOldCell is a copy and only exists in a CellMemento...
// so we need to delete it
if (pOldCell != NULL) delete pOldCell;
}
};
class Sheet {
list<Cell*> cellList; // this is to store all cells to be displayed
list<CellMemento*> stack; // this is to store all the history of the action
int current; // the current action index
list<Cell*>* getList() {return &cellList;}
// add a new pair of old cell and new cell information in a history stack.
void addStack(Cell* pOldCell, Cell* pNewCell) {
while (isRedoable()) {
// if there are reduable tasks are in the stack,
// we need to delete them
list<CellMemento*>::iterator it = stack.begin();
advance(it, (stack.size()-1));
stack.erase(it);
}
// create a new memento object with a pair of old and new cell
// and put that in the stack.
stack.push_back(new CellMemento(pOldCell, pNewCell));
current++;
}
// if the current action index is smaller than the total number of
// actions in the stack, there are redoable tasks in the stack.
bool isRedoable() {return current < (int)stack.size() - 1;}
public:
Sheet() : current(-1) {}
~Sheet() {
// first delete all memento objects (and copies of old cell in them)
list<CellMemento*>::iterator it = stack.begin();
while (it != stack.end()) {
delete *it;
it++;
}
// then delete all cells currently in the sheet.
list<Cell *>::iterator itc = cellList.begin();
while (itc != cellList.end()) {
delete *itc;
itc++;
}
}
string getCellText(int x, int y) {
Cell* pCell = getCell(x, y);
return (pCell != NULL)? pCell->getText() : NULL;
}
Cell* getCell(int x, int y) {
list<Cell*>::iterator it = getList()->begin();
while (it != getList()->end()) {
Cell* pCell = *it;
if ((pCell->getX() == x) && (pCell->getY() == y)) return pCell;
it++;
}
return NULL;
}
// set a new "text" to the specified location (x,y)
void setCellText(int x, int y, string text) {
// first get a pointer of a cell at the specified location.
Cell* pCell = getCell(x, y);
Cell* pOldCell = pCell;
Cell* pNewCell = pCell;
if (pCell != NULL) {
// if pCell is not NULL, there already was a Cell at the specified location
// make a copy of the current cell and keep it as an old cell.
pOldCell = (Cell*)pCell->clone();
pCell->setText(text);
} else {
// otherwise, create a new cell. and keep old cell as NULL.
pNewCell = new Cell(x, y, text);
getList()->push_back(pNewCell);
}
// add a pair of old and new cell to the history stack.
addStack(pOldCell, pNewCell);
}
// it should be noted that "undo" operation itself does not remove a task
// from a history stack.
void undo() {
if (current < 0) return; // nothing to undo...
// first find the current location in the history stack.
list<CellMemento*>::iterator it = stack.begin();
for (int i = 0; it != stack.end(); it++, i++)
if (current == i) break;
CellMemento* memento = *it;
// remove the current cell from the "cellList"
cellList.remove(memento->pNewCell);
// if oldcell is not NULL, put that old cell back in the "cellList"
if (memento->pOldCell != NULL)
cellList.push_back(memento->pOldCell);
if (current >= 0) current--;
}
void redo() {
if (!isRedoable()) return;
// first increment the index of the current task.
current++;
// then find the previous task corresponds to the updated current task index
list<CellMemento*>::iterator it = stack.begin();
for (int i = 0; it != stack.end(); it++, i++)
if (current == i) break;
CellMemento* pMemento = *it;
// then re-apply the task.
if (pMemento->pOldCell != NULL)
cellList.remove(pMemento->pOldCell);
cellList.push_back(pMemento->pNewCell);
}
void display() {
list<Cell*>::iterator it = getList()->begin();
while (it != getList()->end()) {
cout << "x: " << (*it)->getX() << " ";
cout << "y: " << (*it)->getY() << " ";
cout << "Text: " << (*it)->getText() << endl;
it++;
}
}
};
int main(){
Sheet sheet;
sheet.setCellText(1,1,"t1");
sheet.setCellText(3,4,"t2");
sheet.setCellText(3,4,"t3");
sheet.setCellText(5,5,"t4");
sheet.display();
sheet.undo();
sheet.undo();
sheet.display();
sheet.redo();
sheet.display();
}