从键盘输入一个表达式,试编写算法计算表达式的值。

从键盘输入一个表达式,试编写算法计算表达式的值。我刚开始学数据结构,发现有些东西比较有意思,写下来给大家分享下,第一次写博客,不好勿喷。

这道题目是数据结构中很基本的题目。是一个四则运算。刚开始按照我的想法这个题是比较简单的,但是在写的过程中也遇到了一些麻烦!这个四则运算也算是一个算法,是逆波兰算法,这个算法的重要的一点就是中缀转后缀,说的明白一些就是将1+1-3转换为1 1 + 3 -的形式,当然具体也需要对于乘除,括号的转制!

我写这道题是用了两个结构体,分别储存输入的运算符以及数字!是有了一定的要求,需要在输入的时候实现输入一个数字或者是输入一个运算符的时候中间加上空格。这样能保证不用在将输入的字符串分开,少了点麻烦,弊端就是输入的时候不方便!写这个程序要对栈有一定的了解。通过输入的数字与运算符进行入栈,数字是直接入栈。运算符是在入栈的时候判断优先级。小的直接入栈。大的。将运算后在入栈。那个要求自己也可以写代码将它去掉!代码如下:

suanfa.cpp:
#include
#include
using namespace std;
#include "hanshu.h"
#include "Status.h"
#include "han.h"


int main()
{
SqStack S;
Sq S1;
string ch;
char e;
double n;
double a,b,m;
char c;
cout<<"计算器"<cout<<"输入时请输入完成一个数字或符号按下空格"<InitStack(S);//运算符栈
Push(S,'#');
InitStack(S1);//字符栈
cin>>ch; //由于输入的不一定是一个数字,所以用字符串
while(ch!= "=")
{
if(panduan(ch) == 1)//判断输入的是数字字符的话就把字符转换成数字
{

n = zhuanhuan(ch);

Push(S1,n);
cin>>ch;

}
else //是字符的话运行下面
{
c = ch[0]; //将运算符的字符串转化为字符
switch(Precede(GetTop(S,e),c))//比较运算级别
{
case '<': //如果运算级别小的话直接压入栈中
Push(S,c);
cin>>ch;
break;
case '>': //级别大的话将数字栈中输出两个数字,运算后在压入栈!
Pop(S,e);
Pop(S1,b);
Pop(S1,a);

m = yunsuan(a,e,b);

Push(S1,m);
break;
case '=':
Pop(S,e);

cin>>ch;
break;
}
}
while(ch == "="&&(GetTop(S,e)!='#'))//这个循环就是我没有实现将运算符栈中输出完,这个就是将{//栈中输出完!

Pop(S,e);
Pop(S1,b);
Pop(S1,a);

m = yunsuan(a,e,b);

Push(S1,m);
}


}

S1.t--;
cout<<*S1.t<return 0;
}

han.h: //数字栈
#include
using namespace std;
#include




typedef struct
{
double *b;
double *t;
double s;
}Sq;


double zhuanhuan(string ch)
{
double n;
int i = 0;
while(ch[i]!='\0')
{
n =n * 10 + (ch[i]-'0');
i++;
}
return n;
}




int InitStack(Sq &S1)
{
S1.b = new double[MAXSIZE];
if(!S1.b)
exit(OVERFLOW);
S1.t = S1.b;
S1.s = MAXSIZE;
return OK;
}


int Push(Sq &S1,double e)
{
if(S1.t-S1.b == S1.s)
{
return ERROR;
}
*S1.t = e;

S1.t++;
return OK;
}






int Pop(Sq &S1,double &e)
{
if(S1.t == S1.b)
{
return ERROR;
}

S1.t--;
e = *S1.t;
return OK;
}

hanshu.h: //运算符栈
#include
#include
using namespace std;
#include "Status.h"




typedef struct
{
char *base;
char *top;
int stacksize;
}SqStack;




int panduan(string ch)
{
if(ch=="+"||ch=="-"||ch=="*"||ch=="/"||ch=="("||ch==")"||ch=="#")
{

return ERROR;
}
else
{

return OK;
}
}


int InitStack(SqStack &S)
{
S.base = new char[MAXSIZE];
if(!S.base)
exit(OVERFLOW);
S.top = S.base;
S.stacksize = MAXSIZE;
return OK;
}


void StackTraverse(SqStack S)
{
char *p;
p=S.base;
while(p!=S.top)
{
cout<<*p++<<"  ";
}
cout< }


int Push(SqStack &S,char e)
{
if(S.top-S.base == S.stacksize)
{
return ERROR;
}
*S.top = e;

S.top++;
return OK;
}






int Pop(SqStack &S,char &e)
{
if(S.top == S.base)
{
return ERROR;
}
S.top--;
e = *S.top;

return OK;
}




char GetTop(SqStack S,char e)
{
if(S.top == S.base)
exit(1);
e = *(--S.top);

return e;
}


char Precede(char e,char c) //优先级的比较
{


if(e =='#')
{
return '<';
}
else
{

switch(c)
{
case '+':
if(e == '(')
return '<';
else
return '>';
break;
case '-':
if(e == '(')
return '<';
else
return '>';
break;
case '*':
if(e == '*' || e == '/')
return '>';
else
return '<';
break;
case '/':
if(e == '*'||e == '/')
return '>';
else 
return '<';
break;
case '(':
return '<';
break;
case ')':
if(e == '(')
return '=';
else
return '>';
break;

default:
cout<<"error1"<}
}
}


double yunsuan(double a,char e,double b)
{

switch(e)
{
case '+':
return a+b;
break;
case '-':
return a-b;
break;
case '*':
return a*b;
break;
case '/':
if(b==0)
cout<<"error2"<else
return a/b;
break;
}
}

Status.h:
#define TRUE 1
#define FALSE 0l
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define MAXSIZE 100
typedef int Status;



运算结果如下:

计算器
输入时请输入完成一个数字或符号按下空格
1 + 20 - ( 4 * 3 / 2 ) + 5 = 
20


程序的理解:

比如上面输入的1 + 20 - ( 4 * 3 / 2 ) + 5 = ,在程序中的运行过程就是1 + 20 各自入栈,遇到减号,将1 20出栈,运算加法,进栈,遇到(,直接进栈,接下来4 * 3 各自入栈,遇到/,与前面一样,将12压入数字栈,然后/ 2进栈,遇到),运算,这是,数字栈中应该是21和6,运算符中应该是-,遇到+,执行21-6,数字栈中就是15,最后5和=各自入栈,执行最后的得到结果20。

希望能给你们带来帮助!



你可能感兴趣的:(数据结构)