这个 代码 只能实现是一个字符 一个字符输入
具体实现 比如 执行的18*6的这样的,我们可以用输入字符串的形式输入
遇到操作符就 进OPTR栈 否则a=ch[i]-'0';
然后再 将a 压入栈 具体实现 有兴趣的可以自己实现 有问题 请留言
我们来看下 实现这个部分的 源代码
double Run()
{
double ans=0.0;
initstack(OPTR);
push(OPTR,'#');
initstack(OPND);
char c;
double re=0,op=0,a=0,b=0;//用来得到出栈返回值
c=getchar();//缺点 一次只能输入一次 输入10*2就不行了 后面只要是数字字符就出栈
while (c!='#'||gettop(OPTR)!='#')
{
if (c>='0'&&c<='9')//这里只能输入一个字符了,如果是18*3
{
push(OPND,c-'0');//进栈的时候先转换比后面转更好
c=getchar();
}
else
{
int left=cmp(int(gettop(OPTR))),right=cmp(c);
//cout<<ch[left][right]<<endl;
switch(ch[left][right])//分别获得gettop(OPTR) c对应的下标
{
case '<':
push(OPTR,c);
c=getchar();
break;
case '=': //去括号,进行运算
pop(OPTR,re);
c=getchar();
break;
case '>':
pop(OPTR,op);//让运算符 出来
pop(OPND,b);
pop(OPND,a);
ans=Operate(a,op,b);
push(OPND,ans);
break;
}
}
}
return ans;
}
接下来是全部的源代码:
#include <iostream>
#include <stdlib.h>
using namespace std;
const int MAX_SIZE=100;
struct stack //这里里面的元素不适合字符类型比如8*8=?
{
double *base;
double *top;
int stacksize;
};
/**********************************\
+ - * / ( ) #
+ '>','>','<','<','<','>','>',
- '>','>','<','<','<','>','>',
* '>','>','>','>','<','>','>',
/ '>','>','>','>','<','>','>',
( '<','<','<','<','<','=',' ',
) '>','>','>','>',' ','>','>',
# '<','<','<','<','<',' ','=',
\**********************************/
char ch[7][7]=
{'>','>','<','<','<','>','>',
'>','>','<','<','<','>','>',
'>','>','>','>','<','>','>',
'>','>','>','>','<','>','>',
'<','<','<','<','<','=',' ',
'>','>','>','>',' ','>','>',
'<','<','<','<','<',' ','=',
};
void initstack(stack &s)
{
s.base=new double[MAX_SIZE];
s.top=s.base;
s.stacksize=MAX_SIZE;
}
void push(stack &s,double elem)
{
if (s.top-s.base>MAX_SIZE)
{
s.base=new double [MAX_SIZE+MAX_SIZE];
if (!s.base)
return;
s.top=s.base+s.stacksize;
s.stacksize+=MAX_SIZE;
}
*s.top++=elem;
}
double pop(stack &s,double &elem)//这里pop和gettop是一个意思
{
if (s.top==s.base)
return -1;
return elem=*--s.top;//
}
double gettop(stack &s)
{
if (s.top==s.base)
return -1;
return *(s.top-1); //top指针指的是栈顶元素的下一个位置
}
int cmp(int c)//比较两个运算符的优先关系 把其返回值和数组ch下标联系
{
int index;
switch(c)
{
case '+':
index=0;
break;
case '-':
index=1;
break;
case '*':
index=2;
break;
case '/':
index=3;
break;
case '(':
index=4;
break;
case ')':
index=5;
break;
case '#':
index=6;
break;
}
return index;
}
double Operate(double a,int op, double b) //这里操作符op是int型的,大家可以试下int s=65; s=='a'
{
//a=a-48;//a=a-'0';
//b=b-48;
switch(op)
{
case '+':
return
a+b;
break;
case '-':
return a-b;
break;
case '*':
return a*b;
break;
case '/':
return a/b;//这里 要注意精度
break;
}
return 0;
}
struct stack OPTR,OPND;//分别寄存运算符和操作数
double Run()
{
double ans=0.0;
initstack(OPTR);
push(OPTR,'#');
initstack(OPND);
char c;
double re=0,op=0,a=0,b=0;//用来得到出栈返回值
c=getchar();//缺点 一次只能输入一次 输入10*2就不行了 后面只要是数字字符就出栈
while (c!='#'||gettop(OPTR)!='#')
{
if (c>='0'&&c<='9')//这里只能输入一个字符了,如果是18*3
{
push(OPND,c-'0');//进栈的时候先转换比后面转更好
c=getchar();
}
else
{
int left=cmp(int(gettop(OPTR))),right=cmp(c);
//cout<<ch[left][right]<<endl;
switch(ch[left][right])//分别获得gettop(OPTR) c对应的下标
{
case '<':
push(OPTR,c);
c=getchar();
break;
case '=': //去括号,进行运算
pop(OPTR,re);
c=getchar();
break;
case '>':
pop(OPTR,op);//让运算符 出来
pop(OPND,b);
pop(OPND,a);
ans=Operate(a,op,b);
push(OPND,ans);
break;
}
}
}
return ans;
}
void del(stack &s)
{
delete []s.base;
delete []s.top;
}
int main()
{
double ans=0;
int t;
//cout<<"请输入您要计算表达式的次数:"<<endl;
//cin>>t;
while (1)
{
ans=Run();
cout<<ans<<endl;
del(OPTR);
del(OPND);
//delete []OPTR.base;
//delete []OPTR.top;
//delete []OPND.base;
//delete []OPND.top;
system("pause");
}
return 0;
}
最后补上一句 这里的getchar换成 getch更好 就不会出现第二次输入 出现 死循环
因为 中间 有个换行 getchar不行 getch 是只读入字符的