STL之栈(链表实现)

1 1实验项目二 栈的基本操作及其应用

截止时间:11月17日23:59
课程名称:数据结构
实验目的:
1.掌握栈的定义及实现;
2.掌握利用栈求解算术表达式的方法。
实验要求:
1、 使用链式存储结构完成栈的各种基本操作;
2、 补充完成In©, Preced(t1,t2),Operate(a,theta,b)三个函数。
实验题目:栈的基本操作及其应用
实验过程:
1、通过修改完善教材中的算法3.22,利用栈来实现算术表达式求值的算法。对算法3.22中调用的几个函数要给出其实现过程:
(1) 函数In©:判断c是否为运算符;
(2) 函数Precede(t1,t2):判断运算符t1和t2的优先级;
(3) 函数Operate(a,theta,b):对a和b进行二元运算theta。
2、程序运行时,输入合法的算术表达式(中间值及最终结果要在0~9之间,可以包括加减乘除和括号),便可输出相应的计算结果。
实验提示:(仅供参考,每个函数的具体实现可以有多种方法,希望有创新)

  1. 将栈的定义和实现单独保存在头文件“stack.h”中,然后在表达式求值的源程序中包含此头文件(即#include“stack.h”)。
    2.表达式求值源程序的具体实现
    (1) 主函数如下:
    void main()
    {
    Printf(“请输入算术表达式,并以#结束.\n”);
    Printf(“the result of expression is:%d\n”,EvaluateExpression());
    }
    (2) 函数EvaluateExpression的实现见算法3.22
    (3) 函数In©的实现可以采用以下方式:
    Status In(SElemType c)// 应在前面有定义typedef char SElemType;
    { // 判断c是否为运算符
    switch©
    {
    case’+’:return TRUE;
    ……//补充完整
    default:return FALSE;
    }
    }
    (4) 函数Precede(t1,t2)的实现可以采用以下形式:
    SElemType Precede(SElemType t1,SElemType t2)
    { //根据教材表3.1,判断两个运算符的优先关系
    SElemType f;
    switch(t2)
    {
    case ‘+’:
    case ‘-’:if(t1==’(’||t1==’#’)
    f=’<’;
    else
    f=’>’;
    break;
    ……//补充完整
    }
    return f;
    }
    (5) 函数Operate(a,theta,b)的实现可以采用以下方式:
    SElemType Operate(SElemType a,SElemType theta,SElemType b)
    {
    SElemType c;
    a=a-48;
    b=b-48;
    switch(theta)
    {
    case’+’:c=a+b+48;
    break;
    ……//补充完整
    }
    return c;
    }

选做内容:进一步改进,使表达式的中间值及最终结果不局限于0~9之间的个位数。(如果完成要在实验报告中注明),如下图:
实验结果:
输入:2*(4-1)+8
输出:14
该程序能够完成个位数的四则运算。
实验分析:
1.栈的操作的特点;
2.列举调试运行过程中出现的错误并分析原因。
要求:
(1) 程序要添加适当的注释,程序的书写要采用缩进格式。
(2) 程序要具在一定的健壮性,即当输入数据非法时,程序也能适当地做出反应。
(3) 程序要做到界面友好,在程序运行时用户可以根据相应的提示信息进行操作。
(4) 上传源程序到课堂派,源程序保存为calculator.cpp。

1栈的实现

#pragma GCC optimize(2)
//#include<bits/stdc++.h>
#include<cstdio>
//#include<cstring>
#include<iostream>

using namespace std;
#define pi acos(-1.0)
#define e exp(1.0)
typedef long long ll;//创建一个栈,插入和删除都在头部进行 
struct Lnode 
{
	ll date;//将决定栈存储的数据类型 
	Lnode *next;
};
struct Sqlist 
{
	Lnode *head;
	ll size;
}List;
void init()
{
	List.head=NULL;//head指向第一个元素 
	List.size=0;
	return ;
}
bool empty()
{
	if(List.size==0)
	return true;
	return false;
}
void push(ll n)
{
	Lnode *pos=new Lnode;
	pos->date=n;
	if(List.size==0)
	pos->next=NULL;
	else
	pos->next=List.head;
	List.head=pos;
	List.size++;
	return ;
}
ll top()
{
	if(empty())
	{
		cout<<"栈已空,执行空操作"<<endl;
		return -1;
	}
	return List.head->date;
}
void pop()
{
	if(empty())
	{
		cout<<"栈已空,执行空操作"<<endl;
		return ;
	}
	Lnode *pos=List.head;
	List.head=pos->next;
	delete pos;
	List.size--;
	return ;
}
ll size()
{
	return List.size;
}
int main()
{
// freopen(".../.txt","w",stdout);
// ios::sync_with_stdio(false);
	ll i,j;
	ll N;
	while(cin>>N)
	{
		init();
		for(i=0;i<N;i++)
		{
			ll n;
			cin>>n;
			push(n);
		}
		while(!empty())
		{
			ll n=top();
			pop();
 			cout<<n<<' ';
		}
		cout<<endl;
	}
	return 0;
}

1用栈实现基本的算术运算

#pragma GCC optimize(2)
#include<bits/stdc++.h>

using namespace std;

#define pi acos(-1.0)
#define e exp(1.0)
typedef long long ll;//实现基本的计算器,用栈将中缀表达式转化为后缀表达式
const ll maxn=300;
string S,s;
string suffix[maxn],infix[maxn];//存储中缀表达式和后缀表达式 
ll sulen,inlen;
ll Tran(string s)
{
	ll sum=0,i,j;
	for(i=0;i<s.length();i++)
	sum=sum*10+s[i]-'0';
	return sum;
}
void Suffix_Infix()//实现中缀表达式到后缀表达式的转换 
{
	ll i,j;
	stack<string>sta;
	inlen=0;
	for(i=0;i<sulen-1;i++)//将中缀表达式转换为后缀表达式 
	{
		if(suffix[i].length()==1)//说明有可能是运算符 
		{
			if(suffix[i][0]=='+'||suffix[i][0]=='-')
			{
				while(!sta.empty())//找到比当前运算符低的 
				{
					string jie=sta.top();
					if(jie[0]=='(')
					break;
					infix[inlen++]=jie;
					sta.pop();
				}
				sta.push(suffix[i]);
			}
			else if(suffix[i][0]=='*'||suffix[i][0]=='/')
			{
				while(!sta.empty())//找到比当前运算符低的 
				{
					string jie=sta.top();
					if(jie[0]=='('||jie[0]=='+'||jie[0]=='-')
					break;
					infix[inlen++]=jie;
					sta.pop();
				}
				sta.push(suffix[i]);
			}
			else if(suffix[i][0]=='(')
			sta.push(suffix[i]);
			else if(suffix[i][0]==')')//遇到 )则将 ( 之前的全部弹出 
			{
				while(!sta.empty())
				{
					string jie=sta.top();
					if(jie[0]=='(')
					{
						sta.pop();
						break;
					}
					infix[inlen++]=jie;
					sta.pop();
				}
			} 
			else//说明也是操作数 
			infix[inlen++]=suffix[i];			
		}
		else
		infix[inlen++]=suffix[i];//如果为操作数直接放进去 
	}
	while(!sta.empty())//把栈里边剩余的输出到infix中 
	{
		infix[inlen++]=sta.top();
		sta.pop();
	}
	return ;
}
double Eva(string *infix)
{
	stack<double>Jie;
	ll i,j;
	for(i=0;i<inlen;i++)//实现后缀表达式的求值 
	{
		if(infix[i][0]>='1'&&infix[i][0]<='9')
		{
			double sum=double(Tran(infix[i]));
			Jie.push(sum);
		}
		else
		{
			double sum=Jie.top();
			Jie.pop();
			double Sum=Jie.top();
			Jie.pop();
			if(infix[i][0]=='+')
			Sum+=sum;
			else if(infix[i][0]=='-')
			Sum-=sum;
			else if(infix[i][0]=='*')
			Sum*=sum;
			else if(infix[i][0]=='/')
			Sum/=sum;
			Jie.push(Sum);
		}
	}
	double sum=Jie.top();
	Jie.pop();
	return sum;
}
int main()
{
// freopen(".../.txt","w",stdout);
	ios::sync_with_stdio(false);
	cout<<"请输入表达式:(支持加减乘除括号多位数操作)"<<endl;
	while(cin>>S)
	{
		ll i,j;
		s="";
		for(i=0;i<S.length();i++)//将操作数和运算符分隔开 
		{
			if(S[i]=='+'||S[i]=='-'||S[i]=='*'||S[i]=='/'||S[i]=='('||S[i]==')')
			{
				s+=' ';
				s+=S[i];
				s+=' ';
			}
			else
			s+=S[i];
		}
		sulen=0;
		stringstream ss(s);
		while(ss>>suffix[sulen++]);//存储操作数和运算符 
		Suffix_Infix();
		cout<<"输出结果:"<<endl;
		cout<<Eva(infix)<<endl;
	} 
	return 0;
}

1请勿直接CV,学习是一种态度

全部评论

相关推荐

美团 后端开发 总包n(15%是股票)
点赞 评论 收藏
分享
joe2333:怀念以前大家拿华为当保底的日子
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务