整理的DS课后题
该死!竟然没答案!!我写了半天竟然没答案!!
几种栈的表示:链栈、数组栈,两栈共享空间
- 纯虚基类
// created on 2020.10.21 by Joe
#ifndef STACK_H
#define STACK_H_
template <typename T>
class stack
{
public:
virtual ~stack() {}
virtual bool empty() const = 0;
virtual int size() const = 0;
virtual T& top() const = 0;
virtual void pop() = 0;
virtual void push(const T& theElement) = 0;
};
#endif
- 链栈
// created on 2020.10.21 by Joe
#ifndef LINKEDSTACK_H_
#define LINKEDSTACK_H_
#include <sstream>
#include "pureBaseStack.h"
template <typename T>
struct stackNode
{
T element;
stackNode* next;
stackNode() = default;
stackNode(const T& theElement) : element(theElement) {}
stackNode(const T& theElement, stackNode<T>* theNext) : element(theElement), next(theNext) {}
};
template <typename T>
class linkedStack : public stack<T>
{
public:
~linkedStack();
linkedStack(int initialCapacity = 10);
bool empty() const override final { return stackSize == 0; }
int size() const override final{ return stackSize; }
T& top() const override final;
void pop();
void push(const T& theElement);
private:
stackNode<T>* stackTop;
int stackSize;
};
template <typename T>
linkedStack<T>::~linkedStack()
{
while (stackTop != nullptr)
{
stackNode<T>* nextNode = stackTop->next;
delete stackTop;
stackTop = nextNode;
}
}
template <typename T>
linkedStack<T>::linkedStack(int initialCapacity)
{
if (initialCapacity < 1)
{
std::ostringstream s;
s << "can't creat a stack with capacity <= 0!" << std::endl;
throw s.str();
}
stackSize = 0;
stackTop = nullptr;
}
template <typename T>
T& linkedStack<T>::top() const
{
if (stackSize == 0)
{
std::ostringstream s;
s << "Stack is empty!" << std::endl;
throw s.str();
}
return stackTop->element;
}
template <typename T>
void linkedStack<T>::pop()
{
if (stackSize == 0)
{
std::ostringstream s;
s << "can't pop from an empty stack!" << std::endl;
throw s.str();
}
stackNode<T>* nextNode = stackTop->next;
delete stackTop;
stackTop = nextNode;
stackSize--;
}
template <typename T>
void linkedStack<T>::push(const T& theElement)
{
stackTop = new stackNode<T>(theElement, stackTop);
stackSize++;
}
#endif
- 数组栈
// created on 2020.10.21 by Joe
#ifndef ARRAYSTACK_H_
#define ARRAYSTACK_H
#include <iostream>
#include <sstream>
#include <algorithm>
#include "pureBaseStack.h"
template <typename T>
class arrayStack : public stack<T>
{
public:
~arrayStack() { delete[]element; }
arrayStack(int initialCapacity = 10);
bool empty() const override final { return stackTop == -1; }
int size() const override final { return stackTop + 1; }
//void reSetArrayLength();
T& top() const override final;
void pop();
void push(const T& theElement);
private:
T* element;
int stackTop;
int arrayLength;
};
template <typename T>
arrayStack<T>::arrayStack(int initialCapacity)
{
if (initialCapacity < 1)
{
std::ostringstream s;
s << "can't creat a stack with capacity <= 0!" << std::endl;
throw s.str();
}
element = new T[initialCapacity];
stackTop = -1;
arrayLength = initialCapacity;
}
//template <typename T>
//void arrayStack<T>::reSetArrayLength()
//{
// T* temp = new T[arrayLength / 2];
// std::cout << "arrayLength/2 = " << arrayLength / 2 << std::endl;
// std::copy(element, element + stackTop + 1, temp);
// delete[]element;
// arrayLength /= 2;
// element = temp;
//}
template <typename T>
T& arrayStack<T>::top() const
{
if (stackTop == -1)
{
std::ostringstream s;
s << "Stack is empty!" << std::endl;
throw s.str();
}
return element[stackTop];
}
template <typename T>
void arrayStack<T>::pop()
{
if (stackTop == -1)
{
std::ostringstream s;
s << "can't pop from an empty stack!" << std::endl;
throw s.str();
}
element[stackTop--].~T();
//if (stackTop <= arrayLength / 4)
//reSetArrayLength();
}
template <typename T>
void arrayStack<T>::push(const T& theElement)
{
if (stackTop == arrayLength - 1)
{
arrayLength *= 2;
T* temp = new T[arrayLength];
std::copy(element, element + stackTop + 1, temp);
delete[]element;
element = temp;
}
element[++stackTop] = theElement;
}
#endif
- 两栈共享空间
// created on 2020.10.21 by Joe
#ifndef TWOSTACKS_H_
#define TWOSTACKS_H_
#include <sstream>
#include <iostream>
template <typename T>
class twoStack
{
public:
~twoStack() { delete[]element; }
twoStack(int initialCapacity = 10);
bool empty() const { return stackTop1 == -1 && stackTop2 == arrayLength; }
int size() const { return stackTop1 - stackTop2 + arrayLength + 1; }
T& top(int stackNumber) const;
void pop(int stackNumber);
void push(int stackNumber, const T& theElement);
private:
T* element;
int stackTop1;
int stackTop2;
int arrayLength;
void check(int stackNumber) const;
};
template <typename T>
void twoStack<T>::check(int stackNumber) const
{
if (stackNumber < 1 || stackNumber > 2)
{
std::ostringstream s;
s << "stackNumber input error!" << std::endl;
throw s.str();
}
}
template <typename T>
twoStack<T>::twoStack(int initialCapacity)
{
element = new T[initialCapacity];
arrayLength = initialCapacity;
stackTop1 = -1;
stackTop2 = arrayLength;
}
template <typename T>
T& twoStack<T>::top(int stackNumber) const
{
check(stackNumber);
switch (stackNumber)
{
case 1:
if (stackTop1 == -1)
{
std::ostringstream s;
s << "stack1 is empty!" << std::endl;
throw s.str();
}
return element[stackTop1];
break;
case 2:
if (stackTop2 == arrayLength)
{
std::ostringstream s;
s << "stack2 is empty!" << std::endl;
throw s.str();
}
return element[stackTop2];
break;
}
}
template <typename T>
void twoStack<T>::pop(int stackNumber)
{
check(stackNumber);
switch (stackNumber)
{
case 1:
if (stackTop1 == -1)
{
std::ostringstream s;
s << "stack1 is empty!" << std::endl;
throw s.str();
}
element[stackTop1--].~T();
break;
case 2:
if (stackTop2 == arrayLength)
{
std::ostringstream s;
s << "stack2 is empty!" << std::endl;
throw s.str();
}
element[stackTop2++].~T();
break;
}
}
template <typename T>
void twoStack<T>::push(int stackNumber, const T& theElement)
{
check(stackNumber);
if (stackTop1 + 1 == stackTop2)
{
T* temp = new T[2 * arrayLength];
std::copy(element, element + stackTop1 + 1, temp);
std::copy(element + stackTop2, element + arrayLength, temp + arrayLength + stackTop2);
delete[]element;
element = temp;
stackTop2 = arrayLength + stackTop2;
arrayLength *= 2;
}
switch (stackNumber)
{
case 1:
element[++stackTop1] = theElement;
break;
case 2:
element[--stackTop2] = theElement;
break;
}
}
#endif
几种应用
- 开关盒布线
// check net and judge
#include <iostream>
#include "linkedStack.h"
bool checkBox(int net[], int n)
{
linkedStack<int>* s = new linkedStack<int>(n);
for (int i = 0; i < n; i++)
{
if (!s->empty())
{
if (net[i] == net[s->top()])
s->pop();
else
s->push(i);
}
else
s->push(i);
}
if (!s->empty())
{
std::cout << "box is not routable!" << std::endl;
return false;
}
std::cout << "box is routable!" << std::endl;
return true;
}
- 汉诺塔
#include "arrayStack.h"
#include <iostream>
arrayStack<int> Hanoi[4];
void moveAndShow(int n, int x, int y, int z)
{
if (n > 0)
{
moveAndShow(n - 1, x, z, y);
int d = Hanoi[x].top();
Hanoi[x].pop();
Hanoi[y].push(d);
std::cout << "从" << x << "移动[" << d << "]" << "到" << y << std::endl;
moveAndShow(n - 1, z, y, x);
}
}
void HanoiTower(int n)
{
for (int i = n; i >= 1; i--)
Hanoi[1].push(i);
moveAndShow(n, 1, 2, 3);
}
- 迷宫老鼠
// find path in a maze
#include "arrayStack.h"
#include <iostream>
const int maxn = 100;
int maze[maxn][maxn];
struct position
{
int row, col;
};
bool findPath()
{
int size;
std::cout << "输入迷宫尺寸:";
std::cin >> size;
for (int i = 0; i <= size; i++)
{
maze[0][i] = maze[size + 1][i] = 1;
maze[i][0] = maze[i][size + 1] = 1;
}
arrayStack<position>* path = new arrayStack<position>;
int barrRow, barrCol;
int n;
std::cout << "输入障碍数量:";
std::cin >> n;
for (int i = 0; i < n; i++)
{
std::cin >> barrRow >> barrCol;
while(barrRow < 1 || barrCol < 1 || barrRow > size || barrCol > size)
{
std::cout << "输入的障碍物有误,请输入正确的障碍物坐标:";
std::cin >> barrRow >> barrCol;
}
maze[barrRow][barrCol] = 1;
}
position end;
std::cout << "输入终点位置:";
std::cin >> end.row >> end.col;
while (end.row < 0 || end.col < 0 || end.row > size + 1 || end.col > size + 1)
{
std::cout << "终点位置不符合规范,请重新输入:";
std::cin >> end.row >> end.col;
}
position offset[4];
offset[0].row = 0; offset[0].col = 1;
offset[1].row = 1; offset[1].col = 0;
offset[2].row = 0; offset[2].col = -1;
offset[3].row = -1; offset[3].col = 0;
position here;
here.row = 1; here.col = 1;
maze[1][1] = 1;
int option = 0;
int lastOption = 3;
while (here.row != end.row || here.col != end.col)
{
int r, c;
while (option <= lastOption)
{
r = here.row + offset[option].row;
c = here.col + offset[option].col;
if (maze[r][c] == 0) break;
option++;
}
if (option <= lastOption)
{
path->push(here);
here.row = r;
here.col = c;
maze[r][c] = 1;
option = 0;
}
else
{
if (path->empty())
return false;
position next = path->top();
path->pop();
if (next.row == here.row)
option = 2 + next.col - here.col;
else
option = 3 + (next.row - here.row) % 4;
here = next;
}
}
while (!path->empty())
{
std::cout << "(" << path->top().row << "," << path->top().col << ")" << std::endl;
path->pop();
}
return true;
}
- 离线等价类
// offline equiralence classes
#include <iostream>
#include "arrayStack.h"
bool offlineEquiralenceClasses()
{
int n, r;
std::cin >> n;
if (n < 2)
{
std::cout << "can't calculate set with elements < 2" << std::endl;
return false;
}
std::cin >> r;
if (r < 2)
{
std::cout << "can't calculate set with relations < 2" << std::endl;
return false;
}
arrayStack<int>* list = new arrayStack<int>[n + 1];
int a, b;
for (int i = 1; i <= r; i++)
{
std::cin >> a >> b;
list[a].push(b);
list[b].push(a);
}
arrayStack<int> unprocessedList;
bool *out = new bool[n + 1];
for (int i = 1; i <= n; i++)
out[i] = false;
int tol = 1;
for (int i = 1; i <= n; i++)
{
if (!out[i])
{
std::cout << "class " << tol << " is:" << " [" << i << ",";
out[i] = true;
unprocessedList.push(i);
while (!unprocessedList.empty())
{
int j = unprocessedList.top();
unprocessedList.pop();
while (!list[j].empty())
{
int q = list[j].top();
list[j].pop();
if (!out[q])
{
std::cout << q << ",";
out[q] = true;
unprocessedList.push(q);
}
}
}
std::cout << "]" << std::endl;
tol++;
}
}
return true;
}
- 括号匹配
#include "arrayStack.h"
#include <string>
// complexity of time:O(s.size())
// extra complexity of space:O(s.size())
bool matchWithStack(const std::string& s)
{
arrayStack<char> matchStack;
char temp;
for (int i = 0; i < s.size(); i++)
{
if (s[i] == '{' || s[i] == '[' || s[i] == '(')
matchStack.push(s[i]);
else if (s[i] == '}' || s[i] == ']' || s[i] == ')')
{
temp = matchStack.top();
if (temp == s[i])
matchStack.pop();
}
}
if (!matchStack.empty())
return true;
return false;
}
- 列车重排
#include "arrayStack.h"
arrayStack<int>* rails;
int numberOfCars;
int numberOfTrails;
int smallestCar;
int itsTrail;
void outputCarFromTrail()
{
rails[itsTrail].pop();
smallestCar = numberOfCars + 1;
for (int i = 1; i <= numberOfTrails; i++)
{
if (!rails[i].empty() && rails[i].top() < smallestCar)
{
smallestCar = rails[i].top();
itsTrail = i;
}
}
}
bool inputCarToTrail(int n)
{
int bestTrail = 0;
int bestTop = numberOfCars + 1;
for (int i = 1; i <= numberOfTrails; i++)
{
if (!rails[i].empty())
{
int d = rails[i].top();
if (n < d && d < bestTop)
{
bestTop = d;
bestTrail = i;
}
}
else
bestTrail = i;
}
if (bestTrail == 0) return false;
rails[bestTrail].push(n);
if (n < smallestCar)
{
smallestCar = n;
itsTrail = bestTrail;
}
return true;
}
bool railRoad(int input[], int theNumberOfCars, int theNumberOfTrails)
{
numberOfCars = theNumberOfCars;
numberOfTrails = theNumberOfTrails;
rails = new arrayStack<int>[theNumberOfTrails + 1];
smallestCar = numberOfCars + 1;
int nextCarToOutput = 1;
for (int i = 1; i <= numberOfCars; i++)
{
if (input[i] == nextCarToOutput)
{
nextCarToOutput++;
while (smallestCar == nextCarToOutput)
{
outputCarFromTrail();
nextCarToOutput++;
}
}
else
if (!inputCarToTrail(input[i]))
return false;
}
return true;
}
调用的主函数(屁用没有)
// created on 2020.10.21 by Joe
#include <iostream>
using namespace std;
int main()
{
return 0;
}