DS

整理的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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值