ch9 模 板

一、冒泡排序函数模板

主程序测试整形数组、字符数组、字符串数组的排序(不使用STL)

//本程序实现从大到小排序
#include<iostream>
#include<string>
using namespace std;
template<typename T>
void BubbleSort(T a[], int n) {
	for (int i = 1; i < n; i++) {
		int temp = i;
		T tmp;
		for (int j = i - 1; j >= 0; j--) {
			if (a[temp] > a[j]) {
				tmp = a[temp];
				a[temp] = a[j];
				a[j] = tmp;
				temp = j;
			}
			else break;
		}
	}
}
int n;
int t;
int main() {
	cout << "请选择输入元素类型(1、整型,2、字符,3、字符串):";
	cin >> t;
	cout << "请输入元素个数:";
	cin >> n;
	int *a = new int[n];
	char *b = new char[n];
	string *c = new string[n];
	cout << "请输入元素:";
	switch (t) {
	case 1:
		for (int i = 0; i < n; i++) {
			cin >> a[i];
		}
		BubbleSort(a, n);
		for (int i = 0; i < n; i++) {
			cout << a[i] << ' ';
		}
		break;
	case 2:
		for (int i = 0; i < n; i++) {
			cin >> b[i];
		}
		BubbleSort(b, n);
		for (int i = 0; i < n; i++) {
			cout << b[i] << ' ';
		}
		break;
	case 3:
		for (int i = 0; i < n; i++) {
			cin >> c[i];
		}
		BubbleSort(c, n);
		for (int i = 0; i < n; i++) {
			cout << c[i] << ' ';
		}
		break;
	}
	return 0;
}

二、类模板

Step1:设计一个通用的栈类(不使用STL),包含以下操作:

构造函数

析构函数

拷贝构造函数

判断是否为空

压栈操作

弹出操作

返回当前有几个元素

任意扩充栈大小的操作(resize)

重载赋值运算符

根据需要,设计其他操作

Step2:测试这个栈类模板

int 型栈

Double 栈

Char 栈

String 栈

Student 栈

说明:

栈是一种这样的数据结构:它像一个圆柱形的罐子,有底并且有一个开口。所以存放数据时,先放入的数据在下层,后放进的数据在上层;取出数据时,要按照顺序从上层开始取出。所以栈的操作特点是先进后出,后进先出。比如:把1、2、3放入栈,那么它们要按照3、2、1的顺序出栈;又比如:1、2、3保存在栈中,那么想取出2,操作步骤是:取出3、取出2、再放回3。在栈的操作中,“压栈”就是放入数据,“出栈”或“弹出”就是取出数据。

//Stack.h
#pragma once
#include"student.h"
#include<iostream>
using namespace std;

template <class E>
class Stack {   //顺序栈类定义
private:
    E* elements;			//栈元素存放数组
    int top;				//栈顶指针
    int maxSize;               		//栈最大容量
    void overflowProcess();	//栈的溢出处理
public:
    Stack(int sz = 50) {
        maxSize = sz;
        elements = new E[maxSize];
        top = -1;
    };		//构造函数
	Stack(const Stack<E>& s);         //拷贝构造函数
    ~Stack() { delete[]elements; }   //析构函数
    void Push(E x);	          		//进栈
    bool Pop(E& x);		//出栈
    bool getTop(E& x);		//取栈顶内容
    bool IsEmpty() const { return top == -1; }     //判断是否为空
    bool IsFull() const { return top == maxSize - 1; }    //判断是否为满
	int numOf() { return top+1; }    //返回当前几个元素
	void resize(int len);
	Stack<E>& operator=(Stack<E>& s) {
		top = s.top;
		maxSize = s.maxSize;
		elements = new E[maxSize];
		for (int i = 0; i <= top; i++) {
			elements[i] = s.elements[i];
		}
		return *this;
	}
};
template <class E>
Stack<E>::Stack(const Stack<E>& s) {
	maxSize = s.maxSize;
	top = s.top;
	elements = new E[maxSize];
	for (int i = 0; i <= top; i++) elements[i] = s.elements[i];
}
template <class E>
void Stack<E>::overflowProcess() {
	//私有函数:当栈满则执行扩充栈存储空间处理
	E* newArray = new E[2 * maxSize];				//创建更大的存储数组
	for (int i = 0; i <= top; i++)
		newArray[i] = elements[i];
	maxSize += maxSize;
	delete[]elements;
	elements = newArray;  	//改变elements指针
}

template <class E>
void Stack<E>::Push(E x) {
	//若栈不满, 则将元素x插入该栈栈顶, 否则溢出处理
	if (IsFull()) overflowProcess();	      //栈满
	elements[++top] = x;	     //栈顶指针先加1, 再进栈
}

template <class E>
bool Stack<E>::Pop(E& x) {
	//函数退出栈顶元素并返回栈顶元素的值
	if (IsEmpty()) return false;
	x = elements[top--];	     //栈顶指针退1
	return true;		     //退栈成功
}

template <class E>
bool Stack<E>::getTop(E& x) {
	//若栈不空则函数返回该栈栈顶元素的地址
	if (IsEmpty()) return false;
	x = elements[top];
	return true;
}
template<class E>
void Stack<E>::resize(int len) {
	if (len < top + 1) {
		cout << "the length is not enough!" << endl;
		return;
	}
	E* newArray = new E[len];
	for (int i = 0; i <= top; i++) {
		newArray[i] = elements[i];
	}
	maxSize = len;
	elements = newArray;
}
//student.h
#pragma once
#include"Stack.h"
#include<string>
using namespace std;
class Student {
public:
	Student(string s = "", double c = 0, double sc = 0) {
		name = s;
		credit = c;
		score = sc;
	}
	void setStudentName(string s = "", double c = 0, double sc = 0);
	void show();
	bool check(string);
private:
	string name;
	double credit;
	double score;
};
//student.cpp
#include"student.h"
#include<string>
#include<iostream>
#include<iomanip>
using namespace std;


void Student::setStudentName(string s, double c, double sc)
{
	name = s;
	credit = c;
	score = sc;
}

void Student::show()
{
	cout << "姓名:" << name << endl;
	cout << "学分:" << credit << endl;
	cout << "总成绩" << score << endl;
}

bool Student::check(string s)
{
	return name == s;
}
//main.cpp
#include"Stack.h"
#include"student.h"
#include<iostream>
#include<string>
using namespace std;
string sss[4] = { "asdf", "asfd", "adfsdf", "ffff" };
int main() {
	Stack<int> ints;
	Stack<char> chars;
	Stack<double> doubles;
	Stack<string> strings;
	Stack<class Student> students;
	cout << "Stack<int> test:" << endl;
	cout << "Is empty? " << ints.IsEmpty() << endl;
	cout << "Push ";
	for (int i = 1; i <= 10; i++) {
		ints.Push(i); cout << i << " ";
	}
	cout << "\nnumber of elements: " << ints.numOf() << endl;
	int x;
	
	
	cout << "Is full? " << ints.IsFull() << endl;
	cout << "resize 10" << endl;
	ints.resize(10);
	cout << "Is full? " << ints.IsFull() << endl;
	cout << "copy to Stack<int> stack2, pop stack2" << endl;
	Stack<int> ints1(ints);
	cout << "Pop(getTop) ";
	for (int i = 1; i <= 10; i++) {
		ints1.getTop(x);
		cout << x << " ";
		ints1.Pop(x);
	}
	cout << "\nStack<int> stack3 = stack1" << endl;
	Stack<int> ints2;
	ints2 = ints;
	cout << "pop: " << endl;
	for (int i = 1; i <= 10; i++) {
		ints2.Pop(x);
		cout << x << " ";
	}

	cout << endl;
	cout << "\nStack<double> test:" << endl;
	cout << "Is empty? " << doubles.IsEmpty() << endl;
	cout << "Push ";
	
	for (double i = 0.01; i <= 10; i++) {
		doubles.Push(i); cout << i << " ";
	}
	cout << "\nnumber of elements: " << doubles.numOf() << endl;
	double y;

	cout << "Is full? " << doubles.IsFull() << endl;
	cout << "resize 10" << endl;
	doubles.resize(10);
	cout << "Is full? " << doubles.IsFull() << endl;
	cout << "copy to Stack<double> stack2, pop stack2" << endl;
	Stack<double> doubles1(doubles);
	cout << "Pop(getTop) ";
	for (int i = 1; i <= 10; i++) {
		doubles1.getTop(y);
		cout << y << " ";
		doubles1.Pop(y);
	}
	cout << "\nStack<double> stack3 = stack1" << endl;
	Stack<double> doubles2;
	doubles2 = doubles;
	cout << "pop: " << endl;
	for (int i = 1; i <= 10; i++) {
		doubles2.Pop(y);
		cout << y << " ";
	}


	cout << endl;
	cout << "\nStack<string> test:" << endl;
	cout << "Is empty? " << strings.IsEmpty() << endl;
	cout << "Push ";
	for (int i = 0; i <= 3; i++) {
		strings.Push(sss[i]); cout << sss[i] << " ";
	}
	cout << "\nnumber of elements: " << strings.numOf() << endl;
	string z;

	cout << "Is full? " << strings.IsFull() << endl;
	cout << "resize 4" << endl;
	strings.resize(4);
	cout << "Is full? " << strings.IsFull() << endl;
	cout << "copy to Stack<string> stack2, pop stack2" << endl;
	Stack<string> strings1(strings);
	cout << "Pop(getTop) ";
	for (int i = 0; i <= 3; i++) {
		strings1.getTop(z);
		cout << z << " ";
		strings1.Pop(z);
	}
	cout << "\nStack<string> stack3 = stack1" << endl;
	Stack<string> strings2;
	strings2 = strings;
	cout << "pop: " << endl;
	for (int i = 0; i <= 3; i++) {
		strings2.Pop(z);
		cout << z << " ";
	}
	cout << endl;
	Student ss[4], aa;
	for (int i = 0; i <= 3; i++) {
		ss[i].setStudentName(sss[i], i + 10, i + 20);
		cout << "push student" << i + 1 << ": ";
		ss[i].show();
		cout << endl;
		students.Push(ss[i]);
	}
	for (int i = 0; i <= 3; i++) {
		students.Pop(aa);
		cout << "pop student:";
		aa.show();
		cout << endl;
	}
	return 0;
}

三、类模板

基于上面(题目二)设计的栈模板,设计实现一个简单的四则运算计算器,可以实现如下的操作:

例如:   1 + 2 * 3 – 4 / 2 #   答案:5

              2.5 * 5 + 7 / 2 – 1 #   答案:15

3 + 2 * ( 12 - 9 ) - 8 / 4 #

( 3 + 2 ) * 4 - 18 / ( 1 + 2 * 4 ) + 2 #

3 + 4 #

//Stack.h
#pragma once
#include"Stack.h"
#include<iostream>
using namespace std;

template <class E>
class Stack {   //顺序栈类定义
private:
    E* elements;			//栈元素存放数组
    int top;				//栈顶指针
    int maxSize;               		//栈最大容量
    void overflowProcess();	//栈的溢出处理
public:
    Stack(int sz = 50) {
        maxSize = sz;
        elements = new E[maxSize];
        top = -1;
    };		//构造函数
	Stack(const Stack<E>& s);         //拷贝构造函数
    ~Stack() { delete[]elements; }   //析构函数
    void Push(E x);	          		//进栈
    bool Pop(E& x);		//出栈
    bool getTop(E& x);		//取栈顶内容
    bool IsEmpty() const { return top == -1; }     //判断是否为空
    bool IsFull() const { return top == maxSize - 1; }    //判断是否为满
	int numOf() { return top+1; }    //返回当前几个元素
	void resize(int len);
	Stack<E>& operator=(Stack<E>& s) {
		top = s.top;
		maxSize = s.maxSize;
		elements = new E[maxSize];
		for (int i = 0; i <= top; i++) {
			elements[i] = s.elements[i];
		}
		return *this;
	}
};
template <class E>
Stack<E>::Stack(const Stack<E>& s) {
	maxSize = s.maxSize;
	top = s.top;
	elements = new E[maxSize];
	for (int i = 0; i <= top; i++) elements[i] = s.elements[i];
}
template <class E>
void Stack<E>::overflowProcess() {
	//私有函数:当栈满则执行扩充栈存储空间处理
	E* newArray = new E[2 * maxSize];				//创建更大的存储数组
	for (int i = 0; i <= top; i++)
		newArray[i] = elements[i];
	maxSize += maxSize;
	delete[]elements;
	elements = newArray;  	//改变elements指针
}

template <class E>
void Stack<E>::Push(E x) {
	//若栈不满, 则将元素x插入该栈栈顶, 否则溢出处理
	if (IsFull()) overflowProcess();	      //栈满
	elements[++top] = x;	     //栈顶指针先加1, 再进栈
}

template <class E>
bool Stack<E>::Pop(E& x) {
	//函数退出栈顶元素并返回栈顶元素的值
	if (IsEmpty()) return false;
	x = elements[top--];	     //栈顶指针退1
	return true;		     //退栈成功
}

template <class E>
bool Stack<E>::getTop(E& x) {
	//若栈不空则函数返回该栈栈顶元素的地址
	if (IsEmpty()) return false;
	x = elements[top];
	return true;
}
template<class E>
void Stack<E>::resize(int len) {
	if (len < top + 1) {
		cout << "the length is not enough!" << endl;
		return;
	}
	E* newArray = new E[len];
	for (int i = 0; i <= top; i++) {
		newArray[i] = elements[i];
	}
	maxSize = len;
	elements = newArray;
}
//main.cpp
#include"Stack.h"
#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
bool analysis(string str) {
	for (int i = 0; i < str.length(); i++) {
		if (str[i] == '(' || str[i] == ')' || str[i] == '+' || str[i] == '-' || str[i] == '-' || str[i] == '*' || str[i] == '/') {
			continue;
		}
		else if (str[i] >= '0' && str[i] <= '9') {
			string tmp;
			while (str[i] >= '0' && str[i] <= '9') {
				tmp.push_back(str[i]);
				i++;
			}
			if (str[i] == '.') {
				i++;
				if (str[i] >= '0' && str[i] <= '9') {
					tmp.push_back('.');
					while (str[i] >= '0' && str[i] <= '9')
					{
						tmp.push_back(str[i]);
						i++;
					}
				}
				else {
					return false;
				}
			}
			i--;
		}
		else return false;
	}
	return true;
}
string preop(string s) {
	string n = "";
	for (int i = 0; i < s.length(); i++) {
		if (s[i] == ' ' || s[i] == '#') continue;
		n += s[i];
	}
	return n;
}
string format(string str) {    //部分负数补0
	for (int i = 0; i < str.length(); i++) {
		if (str[i] == '-') {
			if (i == 0) str.insert(0, 1, '0');
			else if (str[i - 1] == '(') {
				str.insert(i, 1, '0');
			}
		}
	}
	return str;
}
double readD(string str, int& m)
{
	int zh = 0;//整数部分
	int w = 1;//符号
	bool flag = false;//小数点
	double xi = 0.0;//小数部分
	double x = 1.0;//位
	int i = 1;
	char ch = str[0];//开读
	while (ch >= '0' && ch <= '9')//整数部分
	{
		zh = zh * 10 + ch - '0';
		ch = str[i++];
		m++;
	}
	while (ch < '0' || ch > '9')//找小数点
	{
		if (ch == '.') { flag = true; m++; }
		if (i >= str.length()) return zh;
		ch = str[i++];
	}
	if (!flag) return zh;//没有返回整数
	while (ch >= '0' && ch <= '9')//小数部分
	{
		x *= 10;
		xi = xi + (ch - '0') / x;
		ch = str[i++];
		m++;
	}
	if (w == 1) return zh + xi;
	else return zh - xi;
}
int priorisp(char x) {
	if (x == '#') return 0;
	if (x == '(') return 1;
	if (x == '^') return 7;
	if (x == '*' || x == '/') return 5;
	if (x == '+' || x == '-') return 3;
	if (x == ')') return 8;
	printf("OPTR error\n");
	return 0;
}
int prioricp(char x) {
	if (x == '#') return 0;
	if (x == '(') return 8;
	if (x == '^') return 6;
	if (x == '*' || x == '/') return 4;
	if (x == '+' || x == '-') return 2;
	if (x == ')') return 1;
	printf("OPTR error\n");
	return 0;
}
int main() {
	string s;
	getline(cin, s);
	s = preop(s);
	cout << s << '=';
	Stack<double> nums;
	Stack<char> ops;
	ops.Push('#');
	if (!analysis(s)) {
		cout << "error!(points, spaces...(初步判断不合法))";
		return 0;
	}
	s = format(s) + '#';
	int idx = 0;
	while (idx < s.length()) {
		if (s[idx] >= '0' && s[idx] <= '9') {
			double n;
			int m = 0;
			n = readD(s.substr(idx, s.length()), m);
			nums.Push(n);
			idx += m;
			if (idx >= s.length()) break;
		}
		else if (s[idx] == '+' || s[idx] == '-' || s[idx] == '*' || s[idx] == '/' || s[idx] == '(' || s[idx] == ')' || s[idx] == '#')
		{
			char option = (char)s[idx];
			char oped, res;
			ops.getTop(oped);
			if (prioricp(option) > priorisp(oped)) {
				ops.Push(option);
				idx++;
			}
			else if (prioricp(option) < priorisp(oped)) {
				char a;
				if (ops.IsEmpty()) {
					cout << "Error!!!(缺少操作符)" << endl;
					return 0;
				}
				ops.Pop(a);
				double b;
				if (nums.IsEmpty()) {
					cout << "ERror!!(缺少操作数)" << endl;
					return 0;
				}
				nums.Pop(b);
				double c;
				if (nums.IsEmpty()) {
					cout << "ERRor!!!(缺少操作数)" << endl;
					return 0;
				}
				nums.Pop(c);
				if (a == '+') nums.Push(c + b);
				else if (a == '-') nums.Push(c - b);
				else if (a == '*') nums.Push(c * b);
				else if (a == '/') nums.Push(c / b);
			}
			else {
				ops.Pop(res);
				idx++;
			}
		}
		else 
		{
			idx++;
			continue;
		}
	}
	if (nums.IsEmpty()) {
		cout << "ERROR!!!(操作数栈为空)" << endl;
		return 0;
	}
	double ans;
	nums.Pop(ans);
	if (nums.IsEmpty()) {
		cout << ans << endl;
	}
	else cout << "ERROR!!!(操作数栈剩余两个数及以上)" << endl;
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值