爲了分配的目的,模擬一堆積木的堆積和堆積(謝天謝地),下面是我最終想到的(見下文)。樁的水平由chars的矢量表示,而樁的不同水平則由指向PileLevel的指針向量處理。這花了我一些時間,但我終於明白,像任何其他數據類型一樣,可以在容器類上推送指針。
第一類定義和一堆的一級處理操作:
#include <iostream>
#include <vector>
using namespace std;
class PileLevel
{
public:
vector<char> elements;
char GetLevelElement(int i);
void SetLevelElement(int i, char newelt);
void PushLevelElement(char newelt);
char PopLevelElement();
int GetLevelSize();
void PrintLevel();
void ClearLevel();
bool isLevelEmpty();
};
char PileLevel::GetLevelElement(int i)
{
return elements.at(i);
}
void PileLevel::SetLevelElement(int i, char newelt)
{
elements.at(i) = newelt;
}
void PileLevel::PushLevelElement(char newelt)
{
elements.push_back(newelt);
}
int PileLevel::GetLevelSize()
{
return elements.size();
}
char PileLevel::PopLevelElement()
{
int lst = GetLevelSize();
//cout << lst << endl;
char eltToRet = elements[lst-1];
//cout << eltToRet << endl;
elements.pop_back();
return eltToRet;
}
void PileLevel::PrintLevel()
{
int ctr=0;
for (ctr = 0; ctr < GetLevelSize(); ctr++)
{
cout << elements.at(ctr) << " " ;
}
cout << endl;
}
void PileLevel::ClearLevel()
{
elements.clear();
}
bool PileLevel::isLevelEmpty()
{
if (elements.size() == 0)
return true;
else
return false;
}
接下來,一個類來處理業務爲堆:
#include <iostream>
#include <vector>
#include "PileLevel.h"
using namespace std;
class BlockPile
{
public:
vector<PileLevel*> Levels;
int PileHeight;
//constructor and destructor
BlockPile();
~BlockPile();
//helper functions
void PrintPile();
int GetPileHeight();
void AddLevel();
void AddLevel(char newElt);
char PopLvlElt(int lvl);
void PopEntireLevel(int lvl);
void DeleteTopLevel();
bool isPileEmpty();
void PushLvlElt(char block, int lvl);
void TryStackOnNewTopLevel(char block);
void TryStackOnLowerLevel(char block, int lvl);
void unStackPile();
//required functions
void clear();
bool isEmpty();
char unStack();
char topBlock();
void stack(char block);
int numBlocks();
};
//BlockPile::BlockPile() //test constructor to make sure basic push capabilities are working
//{
// PileLevel* base = new PileLevel;
// base->PushLevelElement('A');
// base->PushLevelElement('B');
// base->PushLevelElement('C');
// Levels.push_back(base);
// PileLevel* L1 = new PileLevel;
// L1->PushLevelElement('D');
// L1->PushLevelElement('E');
// L1->PushLevelElement('F');
// Levels.push_back(L1);
//}
BlockPile::BlockPile()
{
PileLevel* base = new PileLevel;
base->PushLevelElement('A');
Levels.push_back(base);
}
BlockPile::~BlockPile()
{
while (! isPileEmpty())
{
DeleteTopLevel();
}
}
int BlockPile::GetPileHeight()
{
//cout << "Pile is: " << Levels.size() << " levels high." << endl;
return Levels.size();
}
void BlockPile::PrintPile()
{
int ctr = 0;
int lim = GetPileHeight();
//cout << lim << endl;
if (! isPileEmpty())
{
for (ctr = 0; ctr < lim; ctr++)
{
Levels[ctr]->PrintLevel();
}
cout << endl;
}
else
cout << "Can't print empty pile." << endl;
}
void BlockPile::AddLevel() //add an empty level
{
PileLevel* nuLevel = new PileLevel;
Levels.push_back(nuLevel);
}
void BlockPile::AddLevel(char newElt) //add a new level with one element pushed
{
PileLevel* nuLevel = new PileLevel;
nuLevel->PushLevelElement(newElt);
Levels.push_back(nuLevel);
}
void BlockPile::DeleteTopLevel()
{
PileLevel* delPtr;
int ht = GetPileHeight();
if (! isPileEmpty())
{
delPtr = Levels[ht-1]; //set a pointer to the top level
Levels[ht-1]->ClearLevel(); //clear any remaining data in the top level
Levels[ht-1] = NULL; //disconnect the level from the vector of levels
delete delPtr; //delete the level
Levels.pop_back(); //pop the pointer to the level
}
else
cout << "Pile is empty." << endl;
}
char BlockPile::PopLvlElt(int lvl)
{ char eltToRet;
eltToRet = Levels[lvl]->PopLevelElement();
//cout << Levels[lvl]->GetLevelSize() << endl;
//must take these steps to clean up the pile if element popped was the only item remaining on the level
if (Levels[lvl]->GetLevelSize() == 0)
{
vector<PileLevel*>::iterator ptVecIter = Levels.begin(); //need to declare this iterator and use .begin() because .erase() is defined to take iterator arguments
Levels.erase(Levels.begin() + (lvl));
}
return eltToRet;
}
void BlockPile::PopEntireLevel(int lvl)
{
while (! Levels[lvl]->GetLevelSize() <= 0)
{
cout << Levels[lvl]->PopLevelElement() << " " ;
}
//must take these steps to clean up the pile if element popped was the only item remaining on the level
if (Levels[lvl]->GetLevelSize() == 0)
{
vector<PileLevel*>::iterator ptVecIter = Levels.begin(); //need to declare this iterator and use .begin() because .erase() is defined to take iterator arguments
Levels.erase(Levels.begin() + (lvl));
}
cout << endl;
}
void BlockPile::PushLvlElt(char block, int lvl)
{
if (Levels[lvl]->GetLevelSize() >= 0) //if the current level exists and contains 0 or more elements
Levels[lvl]->PushLevelElement(block);
else if (Levels[lvl] == NULL) //if pointer to current level is NULL
{
Levels[lvl] = new PileLevel;
Levels[lvl]->PushLevelElement(block);
}
else if (lvl > GetPileHeight()) //if lvl is greater than current height of pile
{
AddLevel(block); //add a new level to the pile and push the block on it
}
}
bool BlockPile::isPileEmpty()
{
if (Levels.size() == 0)
return true;
else
return false;
}
void BlockPile::unStackPile()
{
int lim = GetPileHeight() - 1;
while (lim > -1)
{
PopEntireLevel(lim);
lim--;
}
}
void BlockPile::TryStackOnNewTopLevel(char block)
{
int oldTopLvl = GetPileHeight()-1; //get current top level of pile
AddLevel(); //add a dummy new level but don't push anything on it yet
int newTopLvl = GetPileHeight()-1; //get new top level after adding dummy level
int newTopLvlSize = Levels[newTopLvl]->GetLevelSize(); //should be 0
int oldTopLvlSize = Levels[oldTopLvl]->GetLevelSize(); //should be > 0
int sizeDiff = oldTopLvlSize - newTopLvlSize;
//cout << newTopLvlSize << " " << oldTopLvlSize << " " << sizeDiff << endl;
if (sizeDiff >=2) //if difference in size between dummy level and old top level is at least 2
Levels[newTopLvl]->PushLevelElement(block); //push the block on the new top level
else
{
DeleteTopLevel(); //remove the dummy level, not ready for it yet
TryStackOnLowerLevel(block,oldTopLvl); //try to push the block on the next lower level
}
}
void BlockPile::TryStackOnLowerLevel(char block, int lvl)
{
if (lvl == 0) //if at level 0, base of the pile, can't go lower than this
{
Levels[lvl]->PushLevelElement(block); //must push the block at the base
}
else //if not yet at base
{
int thisLvlSize = Levels[lvl]->GetLevelSize(); //get size of current level
int lowerLvlSize = Levels[lvl-1]->GetLevelSize(); //get size of next lower level
int sizeDiff = lowerLvlSize - thisLvlSize; //difference in size
//cout << thisLvlSize << " " << lowerLvlSize << " " << sizeDiff << endl;
if (sizeDiff >= 2) //if size difference is at least 2
Levels[lvl]->PushLevelElement(block); //push block on current level
else //if diff is smaller than 2
TryStackOnLowerLevel(block,lvl-1); //make recursive call and try to push it on a lower level
}
}
//required functions
void BlockPile::clear()
{
int lim = GetPileHeight()-1;
while (lim > -1)
{
DeleteTopLevel();
lim--;
}
}
bool BlockPile::isEmpty()
{
return isPileEmpty();
}
char BlockPile::unStack()
{
int ht = GetPileHeight()-1;
return PopLvlElt(ht);
}
char BlockPile::topBlock()
{
int ht = GetPileHeight()-1;
int lsize = Levels[ht]->GetLevelSize() - 1;
return Levels[ht]->GetLevelElement(lsize);
}
void BlockPile::stack(char block)
{
TryStackOnNewTopLevel(block);
}
int BlockPile::numBlocks()
{
int acc = 0;
int ht = GetPileHeight();
int ctr;
for(ctr = 0; ctr < ht; ctr++)
{
acc = acc + Levels[ctr]->GetLevelSize();
}
return acc;
}
最後一個驅動程序:
#include <iostream>
#include <array>
#include "BlockPile.h"
using namespace std;
int main()
{
//PileLevel myLevel;
//myLevel.PushLevelElement('A');
//myLevel.PushLevelElement('B');
//myLevel.PushLevelElement('C');
//myLevel.PushLevelElement('D');
//myLevel.PrintLevel();
//cout << myLevel.GetLevelSize() << endl;
//myLevel.PopLevelElement();
//myLevel.PrintLevel();
//BlockPile myPile;
//myPile.GetPileHeight();
//myPile.PrintPile();
//myPile.AddLevel('Z');
//myPile.GetPileHeight();
//myPile.PrintPile();
//myPile.PushLvlElt('P', 2);
//myPile.PushLvlElt('Q', 1);
//myPile.PrintPile();
//cout << myPile.PopLvlElt(2) << endl;
//cout << myPile.PopLvlElt(1) << endl;
//cout << myPile.PopLvlElt(0) << endl;
//myPile.PrintPile();
//myPile.DeleteTopLevel();
////myPile.DeleteTopLevel();
//myPile.PrintPile();
//myPile.PushLvlElt('G',0);
//myPile.PushLvlElt('H',0);
//myPile.AddLevel('I');
//myPile.PushLvlElt('J',2);
//myPile.AddLevel('K');
//myPile.PrintPile();
////myPile.PopEntireLevel(3);
////myPile.PopEntireLevel(2);
//myPile.unStackPile();
//myPile.PrintPile();
//BlockPile myPile2;
//myPile2.PrintPile();
//myPile2.TryStackOnNewTopLevel('B');
//myPile2.PrintPile();
//myPile2.TryStackOnNewTopLevel('C');
//myPile2.PrintPile();
//myPile2.TryStackOnNewTopLevel('D');
//myPile2.PrintPile();
//myPile2.TryStackOnNewTopLevel('E');
//myPile2.PrintPile();
//myPile2.TryStackOnNewTopLevel('F');
//myPile2.PrintPile();
array<char,44> BlockSet = {'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '+', '-', '=', '/', '<', '>', '?', ',', '.'};
int BSSize = BlockSet.size();
int idx = 0;
BlockPile myPile3;
myPile3.PrintPile();
//myPile3.clear();
for (idx = 0; idx < BSSize; idx++)
{
myPile3.stack(BlockSet[idx]);
cout << "Number of blocks currently in pile: " << myPile3.numBlocks() << endl;
myPile3.PrintPile();
}
cout << "Top block is: " << myPile3.topBlock() << endl;
cout << endl;
for (idx=0; idx < 5; idx++)
{
cout << "Unstacking block: " << myPile3.unStack() << endl;
cout << "Top block is now: " << myPile3.topBlock() << endl;
cout << "Number of blocks is now: " << myPile3.numBlocks() << endl;
cout << endl;
}
cout << endl;
cout << "Unstacking remainder of pile..." << endl;
myPile3.unStackPile();
system("pause");
return 0;
}
瞧。
這將是一種學習C++的痛苦方式。獲取一本C++書,學習語言。那麼你將會更好地瞭解如何用一種語言表達用不同語言表達的概念。 – DavidO
如何...''#include typedef std :: vector Row_t; typedef std :: vector RLikeSomething_t;''?你可以像這樣訪問:''RLikeSomething_t東西; .... something [row] [column] ='x';'' –
BitTickler