谁能做表达式求值啊 求助!!!!!!!!!!!!!!
做了一个但怎么也出不来!!!!!!!!1 帮你看了一下,光眼看,看不出什么,我一直用C++来写这些,我用VS2008编译器,打不开你那个malloc文件.你若想要一个C++写的,我可以写一个发上来。 或者你可以BAIDU一下的,应该很多这方面的。
谢了兄弟
我一直都是用c没用过c++不过想试试看给我发一个把我看看谢了 昨天写好了,调试到今天,晕。。。。。。。。。我写得是后缀计算表达式,因为现在编译程序一般都是用后缀表达式求解表达式的值。
我用VS2008编译器,经测试通过。如果有什么问题,望告诉一声,谢谢。
我用多文件形势写出来,包含:
栈类"Stack.h","Stack.cpp"
表达式类:"Calculator.h","Calculator.cpp"
还有一个"main.cpp"
大部分程序都有注释,如有不懂,再交流。。 //Stack.h
#ifndef STACK_H
#define STACK_H
typedef double DataType;
#include<iostream>
#include<cstdlib>
using namespace std;
const int MaxStackSize=50;
class Stack
{
private:
DataType stacklist[MaxStackSize];
int top;
public:
Stack();
void Push(const DataType& item); //压入操作
DataType Pop(); //弹出一个元素
void ClearStack(); //清空栈
DataType Peek()const; //访问栈顶元素
int StackEmpty()const; //查看是否为空栈
int StackFull()const; //查看是否已满
};
#endif //Stack.cpp
#include "Stack.h"
Stack::Stack():top(-1){}
void Stack::Push(const DataType& item)
{
//若栈已满,则终止程序
if(top==MaxStackSize-1)
{
cerr<<"Stack overflow!"<<endl;
exit(1);
}
//将top加一并将ITEM拷贝到STACKLIST中
top++;
stacklist[top]=item;
}
DataType Stack::Pop()
{
DataType temp;
if(top==-1) //栈为空,退出
{
cerr<<"Attemp to pop an empty stack!"<<endl;
exit(1);
}
temp=stacklist[top]; //将栈顶元素赋给temp;
//top减一并返回temp
top--;
return temp;
}
DataType Stack::Peek()const //返回栈顶元素的值
{
//若栈为空,退出
if(top==-1)
{
cerr<<"Attemp to peek t an empty stack!"<<endl;
exit(1);
}
return stacklist[top];
}
int Stack::StackEmpty()const //检测栈是否为空
{
return top==-1; //返回top==-1的逻辑值
}
int Stack::StackFull()const //检测栈是否为满
{
//检测top的位置
return top==MaxStackSize-1;
}
void Stack::ClearStack() //从栈中清除所有元素
{
top=-1;
} //Calculator.h
#ifndef CALCULATOR_H
#define CALCULATOR_H
enum Boolean{False,True};
#include "Stack.h"
#include <cmath>
class Calculator
{
private:
Stack s; //存放操作数
void Enter(double num);
Boolean GetTwoOperands(double& opnd1,double &opnd2);
void Compute(char op);
public:
void Run(); //计算表达式
void Clear(); //清空计算器
};
#endif //Calculator.cpp
#include "Calculator.h"
void Calculator::Enter(double num) //住栈中存放数据值
{
s.Push(num);
}
//从栈中取得操作数并赋值给形参,若操作数不够,则打印出错信息,并返回False
Boolean Calculator::GetTwoOperands(double& opnd1,double& opnd2)
{
if(s.StackEmpty()) //检查操作数是否存在
{
cerr<<"Missing operand!"<<endl;
return False;
}
opnd1=s.Pop(); //取右操作数
if(s.StackEmpty())
{
cerr<<"Missing operand!"<<endl;
return False;
}
opnd2=s.Pop(); //取左操作数
return True;
}
void Calculator::Compute(char op)
{
Boolean result;
double operand1,operand2;
//取两个操作数,并判断是否成功取到
result=GetTwoOperands(operand1,operand2);
if(result==True)
switch(op)
{
case '+':
s.Push(operand2+operand1);
break;
case '-':
s.Push(operand2-operand1);
break;
case '*':
s.Push(operand2*operand1);
break;
case '/':
if(operand1==0.0)
{
cerr<<"Divide by 0!"<<endl;
s.ClearStack();
}
else
s.Push(operand2/operand1);
break;
case '^':
s.Push(pow(operand2,operand1));
break;
}
else
s.ClearStack(); //出错!清空计算器
}
void Calculator::Run()
{
char c;
double newoperand;
while(cin>>c&&c!='=') //读入字符,直到遇“=”时退出
{
switch(c)
{
case '+':
case '-':
case '*':
case '/':
case '^':
Compute(c); //读到运算符,求值
break;
default:
//非运算符,则必为操作数,将数字送回
cin.putback(c);
//读入操作符并将其存入栈中
cin>>newoperand;
Enter(newoperand);
break;
}
}
//答案已在栈顶,用peek输出之
if(!s.StackEmpty())
cout<<s.Peek()<<endl;
}
//清空操作数栈
void Calculator::Clear()
{
s.ClearStack();
} //main.cpp
#include "Calculator.h"
int main()
{
Calculator Calc;
Calc.Run();
system("pause");
return 0;
}
前几天写的支持括号,但是只支持正整数
#include<stdio.h>#include<stdlib.h>
#include <ctype.h>
#define Stack_Size 50
typedef struct
{
char elem[Stack_Size];
int top;
}OpStack;
typedef struct
{
int elem[Stack_Size];
int top;
}NumStack;
void Push(OpStack *s,char x);
void Pop(OpStack *s,char *x);
void Push(NumStack *s,int x);
void Pop(NumStack *s,int *x);
int Execute(int a,char c,int b);
int ExpEvaluation(NumStack *OVS,OpStack *OPTR);
void GetNumber(char p);
int Cint(char mychar);
int num=0;
void main()
{
int result;
OpStack OPTR;
NumStack OVS;
OVS.top=-1;OPTR.top=-1;
result=ExpEvaluation(&OVS,&OPTR);
printf("The result is %d\n",result);
}
void Push(OpStack *s,char x)
{
s->top++;
s->elem[s->top]=x;
}
void Pop(OpStack *s,char *x)
{
*x=s->elem[s->top];
s->top--;
}
void Push(NumStack *s,int x)
{
s->top++;
s->elem[s->top]=x;
}
void Pop(NumStack *s,int *x)
{
*x=s->elem[s->top];
s->top--;
}
int Execute(int a,char c,int b)
{
switch(c)
{
case '+':return a+b;break;
case '-':return a-b;break;
case '*':;return a*b;break;
case '/':return a/b;break;
}
}
void GetNumber(char p)
{
num=num*10+Cint(p);
}
int Cint(char mychar)
{
return (mychar-48);
}
//栈运算符与读入运算符优先级的比较
char Compare(char x,char y)
{
char priority='<';
switch(x)
{
case '+':
case '-':if(y=='#'||y=='+'||y=='-'||y==')')priority='>';break;
case '*':
case '/': priority='>';if(y=='(' )priority='<';break;
case '(':if(y==')')priority='=';break;
case '#':if(y=='#') priority='=';break;
default:priority='E';
}
return priority;
}
int ExpEvaluation(NumStack *OVS,OpStack *OPTR)
{
int v,flag=0,f1=1,f2=1;
char ch,ch1,c;
int a,b,flag1=1;
Push(OPTR,'#');
printf("\n\nputin a string(stop with #):");
while(ch!='#'||OPTR->elem[OPTR->top]!='#')
{ if(f1&&f2)
ch=getchar();
if(isdigit(ch))
{
GetNumber(ch);
}
else
{
if((ch>='0'&&ch<='9'||ch1>='0'&&ch1<='9')&&!flag)
{
Push(OVS,num);
num=0;
}
switch(Compare(OPTR->elem[OPTR->top],ch))
{
case '<':
Push(OPTR,ch);
flag=0;
break;
case '>':
Pop(OPTR,&c);
Pop(OVS,&b);
Pop(OVS,&a);
v=Execute(a,c,b);
if(OPTR->elem[OPTR->top]=='-')
{
v=-1*v;
OPTR->elem[OPTR->top]='+';
}
Push(OVS,v);
if(ch!='#'&&ch!=')')
{
Push(OPTR,ch);
flag=0;
}
else
{
f1=0;
flag=1;
}
//printf("%d %c %d %d\n",a,c,b,v);
break;
case '=':
Pop(OPTR,&c);
if(c=='('&&ch==')')
{
f1=1;
flag=1;
}
break;
default:printf("Wrong Express!");exit(0);
}
}
ch1=ch;
}
return(v);
} 呵呵,楼上厉害,我用的是数组,我的整形,浮点都行,还能算平方。我的篇幅太长了,自已看了都头疼,呵呵。。。 我的没办法.因为只能一个一个字符读取..然后还要分析..当然改一下也可以..呵呵.反正是玩玩..等到有时间的时候给它改版..呵呵
谢
强啊 哈哈谢谢啊这是怎么了
为什么在我的机子上不能通过我用的是vc++6.0我没学过c++不要见笑啊 [quote][bo]以下是引用 [un]firel[/un] 在 2008-4-18 17:37 的发言:[/bo]
为什么在我的机子上不能通过我用的是vc++6.0我没学过c++
不要见笑啊 [/quote]
是我的吗,我的在VS2008通过,并测试正确,你用VC6,可以先建一个空的WIN32 console application,然后再一个一个地把文件加进去,注意哪些是头文件,哪些是源文件。
你没学过C++吗?那sunkaidong大哥写得应该看得懂吧,就用他的了。 用楼上的兄弟的..他的很规范..说实在的..我的程序理解有点难... 呵呵,楼上谦虚!
另外,我帮楼主你再看了一下源程序,由于你没写注释,我看得比较累,就没认真看,但发现了几个重要错误,就是你使用的变量i,m都没有初始化,还有就是这个警告:warning C4715: 'precede' : not all control paths return a value
其实该算是个错误了:就是你自定义函数里出了错。你希望函数返回某个值,但是可能在函数里加了if等条件判断,使得一部分情况下有返回值,而另一种情况没返回值。我也帮你改了一下。现在能运行了,但发现你没写最后结果的输出函数,这个就你自已加了。呵呵。。。 //下面是我帮你改的:
#include<stdio.h>
#include<malloc.h>
#include<string.h>
#define num 20
typedef struct stackf
{
int *top;
int *base;
}stack1;
typedef struct stackl
{
char *top;
char *base;
}stack2;
char precede(char x,char y)
{
switch(x)
{
case '+':
if(y=='+'||y=='-'||y==')'||y=='#')
return '>';
else
return '<';
case '-':
if(y=='+'||y=='-'||y==')'||y=='#')
return '>';
else
return '<';
case '*':
if(y=='(')
return '<';
else
return '>';
case '/':
if(y=='(')
return '<';
else
return '>';
case '(':
if(y==')')
return '=';
else
if(y=='#')
break;
else
return '<';
case ')':
if(y=='(')
break;
else
return '>';
case '#':
if(y=='#')
return '=';
else
if(y==')')
break;
else
return '<';
}
return 1;
}
void init_stack1(stack1 *st)
{
st->base=(int *)malloc(num*sizeof(int));
st->top=st->base;
}
void init_stack2(stack2 *st)
{
st->base=(char *)malloc(num*sizeof(char));
st->top=st->base;
}
int empty_stack1(stack1 *st)
{
if(st->base==st->top)
return 1;
return 0;
}
int empty_stack2(stack2 *st)
{
if(st->base==st->top)
return 1;
return 0;
}
int full_stack1(stack1 *st)
{
if(st->top-st->base>=num)
return 1;
return 0;
}
int full_stack2(stack2 *st)
{
if(st->top-st->base>=num)
return 1;
return 0;
}
void push1(stack1 *st,int x)
{
if(full_stack1(st))
printf("error");
else
*st->top++=x;
}
void push2(stack2 *st,int x)
{
if(full_stack2(st))
printf("error");
else
*st->top++=x;
}
int pop1(stack1 *st)
{
int shuzi;
shuzi=--*st->top;
return shuzi;
}
char pop2(stack2 *st)
{
char zimu;
zimu=--*st->top;
return zimu;
}
char get_top2(stack2 *st)
{
return *(st->top-1);
}
int operter(int num1,char oper,int num2)
{
switch(oper)
{
case '+':
return num1+num2;
break;
case '-':
return num1-num2;
break;
case '*':
return num1*num2;
break;
case '/':
return num1/num2;
}
return 1;
}
void open()
{
printf("****************************************\n");
printf("***作者----------------冯亮*************\n");
printf("***计算机0602--------------*************\n");
printf("****************************************\n");
printf("****请输入您想的操作********************\n");
printf("0-----------------退出\n");
printf("1-----------------输入表达式\n");
printf("2-----------------使用说明\n");
}
void readme()
{
printf("****************************************\n");
printf("输入数据!!\n");
printf("例如 ----1+2*3-4#以#号结束\n");
printf("谢谢使用^_^!\n");
printf("****************************************\n");
}
void main()
{
int i,x,num1,num2,m=0,e;
char oper;
stack1 s;
stack2 r;
char a[20];
init_stack1(&s);
init_stack2(&r);
push2(&r,'#');
while(1)
{
open();
scanf("%d",&i);
switch(i)
{
case 0:
break;
case 1:
printf("请输入表达式!!!!!!!!\n");
scanf("%s",a);
while(a[m]!='#')
{
x=a[m];
if(x>=60&&x<=69)
{
if(a[m-1]>=60&&a[m-1]<=69&&m>0)
{
e=pop1(&s);
e=e*10+(int)(x-'0');
}
else
e=(int)(x-'0');
push1(&s,e);
m++;
}
else
{
switch(precede(get_top2(&r),x))
{
case '<':
push2(&r,x);
break;
case '>':
num1=pop1(&s);
num2=pop1(&s);
oper=pop2(&r);
push1(&s,operter(num1,oper,num2));
break;
case '=':
pop2(&r);
break;
}
m++;
}
}
break;
case 2:
readme();
break;
default :
printf("error");
break;
}
}
} 那个结果问题是我故意的..毕竟我的运算函数只有四个操作符号.....结果有输出啊....没有结果不好判断对错了...呵呵...
[[it] 本帖最后由 sunkaidong 于 2008-4-18 19:06 编辑 [/it]]
页:
[1]
2
