(C++) 输入一个由数字、+、-、*、/及括号组成的自述表达式,求其值。

C++ 如题, 要正确的 答对加分。 谢谢!
简单的怎么不给了???

我学数据结构时做过一个实验,跟这个很像,不过我还扩展了一下,可以计算小数、负数,得分很高哦。。。
.........stack.h...................
#define STACK_INIT_SIZE 10 /* 存储空间初始分配量 */
#define STACKINCREMENT 2 /* 存储空间分配增量 */
typedef float SElemType_f;
typedef char SElemType_ch;
typedef int Status;
#include<iostream.h>
#include<stdlib.h> /*free()头文件 */
#define OK 1
#define ERROR 0
typedef struct SqStack_f{ /* 运算数栈 */
SElemType_f *base; /* 在栈构造之前和销毁之后,base的值为NULL */
SElemType_f *top; /* 栈顶指针 */
int stacksize; /* 当前已分配的存储空间,以元素为单位 */
}SqStack_f; /* 顺序栈 */
typedef struct SqStack_ch{ /* 定义运算符栈 */
SElemType_ch *base; /* 在栈构造之前和销毁之后,base的值为NULL */
SElemType_ch *top; /* 栈顶指针 */
int stacksize; /* 当前已分配的存储空间,以元素为单位 */
}SqStack_ch; /* 顺序栈 */
Status InitStack(SqStack_f &S){ /* 构造一个运算数栈S */
S.base=new SElemType_f[STACK_INIT_SIZE];
if(!S.base)
exit(ERROR); /* 存储分配失败 */
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
return OK;
}
Status InitStack(SqStack_ch &S){ /* 构造一个运算符栈S */
S.base=new SElemType_ch[STACK_INIT_SIZE];
if(!S.base)
exit(ERROR); /* 存储分配失败 */
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
return OK;
}
float GetTop_f(SqStack_f &S){ /* 若栈不空,则用e返回运算数栈S的栈顶元素,并返回OK;否则返回ERROR */
float e;
if(S.top==S.base)
return ERROR;
e=*(S.top-1);
return e;
}
char GetTop_ch(SqStack_ch &S){ /* 若栈不空,则用e返回运算符栈S的栈顶元素,并返回OK;否则返回ERROR */
char e;
if(S.top==S.base)
return ERROR;
e=*(S.top-1);
return e;
}
void Push_f(SqStack_f &S,SElemType_f e){ /* 插入元素e为新的栈顶元素 */
if(S.top-S.base==S.stacksize) /* 栈满 */
cout<<"栈满,无法压栈!"<<endl;
*S.top++=e;
}
void Push_ch(SqStack_ch &S,SElemType_ch e){ /* 插入元素e为新的栈顶元素 */
if(S.top-S.base==S.stacksize) /* 栈满 */
cout<<"栈满,无法压栈!"<<endl;
*S.top++=e;
}
float Pop_f(SqStack_f &S,float &e){ /* 若栈不空,则删除运算数栈S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR */
if(S.top==S.base)
return ERROR;
e=*--S.top;
return e;
}
char Pop_ch(SqStack_ch &S,char &e){ /* 若栈不空,则删除运算符栈S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR */
if(S.top==S.base)
return ERROR;
e=*--S.top;
return e;
}

.........calculator.cpp.............
#include"stack.h" //自己定义的栈的头文件
#include <stdio.h> //getchar()头文件
#include<string.h>
char Precede(char t1,char t2)
{ // 判断两符号的优先关系
char f;
switch(t2){
case '+':
case '-':if(t1=='('||t1=='=')
f='<';
else
f='>';
break;
case '*':
case '/':if(t1=='('||t1=='='||t1=='+'||t1=='-')
f='<';
else
f='>';
break;
case '(':if(t1==')'){
cout<<"您的输入有误,请重新输入!"<<"\n"; //提示出错
exit(0);
}
else
f='<';
break;
case ')':if(t1=='='){
cout<<"您的输入有误,请重新输入!"<<"\n"; //提示出错
exit(0);
}
else if(t1=='(')
f='=';
else f='>';
break;
case '=':if(t1=='('){
cout<<"您的输入有误,请重新输入!"<<"\n"; //提示出错
exit(0);
}
else if(t1=='=')
f='=';
else f='>';
break;
}
return f;
}
int In(char c){ //判断c是否为运算符
int i;
switch(c){
case '+':
case '-':
case '*':
case '/':
case '(':
case ')':
case '=':return OK;
default:return ERROR;
}
return i;
}
float Operate(float a,char theta,float b){ //进行运算的函数
float c;
switch(theta){
case '+':c=a+b;break;
case '-':c=a-b;break;
case '*':c=a*b;break;
case '/':if(b==0.0){
cout<<"分母不能为零!"<<endl;exit(0);
}
c=a/b;break;
default:cout<<"错误的运算符!"<<endl;
}
return c;
}
float EvaluateExpression(){
// 算术表达式求值的算符优先算法。设OPTR和OPND分别为运算符栈和运算数栈
SqStack_f OPND;
SqStack_ch OPTR;
char c,x,theta;
char buf[16]; //将运算数存入buf[]数组
float a,b;
int i=0;
char line[100];
int h=0;
cin.getline(line,100); //读入一行字符
float j=10,k=0,z=0.0;
InitStack(OPTR); Push_ch(OPTR,'=');
InitStack(OPND);
c=line[h];
int l=strlen(line);
if(c=='-'){ //若第一个字符是'-',说明是负号,相当于 “0 -”,所以将0存入buf中
buf[0]=0;
i=1;
}
for(int m=0;m<l-1;m++){ //若等号不是出现在表达式的最末一位,提示错误
if(line[m]=='='){
cout<<"等号输入有误!"<<endl;exit(0);
}
}
if(strlen(line)==0||c=='='){ //未输入字符或只有一个“=”时,给出提示
cout<<"您没有输入表达式!"<<endl;exit(0);
}
if(line[strlen(line)-1]!='='){ //表示式不是以“=”结束时,提示错误
cout<<"未输入等号!"<<endl;exit(0);
}

while(c!='='||GetTop_ch(OPTR)!='='){ //依次读入字符,直到表达式求值完毕
if(!In(c)){ //非运算符的情况
if(c>='0'&&c<='9'){ //c为0~9之间的运算数
if(k==0){ //k为已出现的小数点的个数
buf[i]=c;
z=z*10+c-48; //小数点之前z的表达式
i++;
}
else if(k==1){ //出现小数点后
buf[i]=c;
z=z+(c-48)/j; //小数点之后每位都要缩小相应的倍数
j*=10;
i++;
}
else{
cout<<"小数点输入错误!"<<endl;exit(0); //提示错误并退出
}
}
else if(c=='.'){
k++; //每出现一个小数点,k的值加一
i++;
}
else{
cout<<"您输入了非法字符!"<<endl;exit(0); //输入了非法字符,退出
}
h++;
c=line[h];
}
else{
if(i>0){ //即buf[]内有运算数存在
Push_f(OPND,z); //将运算数压入运算数栈
z=0.0; //分别将z、i置零,j=10,准备下一次转换运算数并存储
k=0;j=10;
i=0;
}
if(line[h]=='('&&line[h+1]=='-') //某个字符是'(',且下一个字符是'-',说明是负号,相当于 “0 -”,所以将0压入运算数栈中
Push_f(OPND,0);
switch(Precede(GetTop_ch(OPTR),c)){ //比较OPTR栈顶元素和c的优先级
case '<': //c进OPTR栈
Push_ch(OPTR,c);
h++;
c=line[h];
break;
case '=': //弹出左括号
Pop_ch(OPTR,x);
h++;
c=line[h];
break;
case '>': //栈顶运算符退栈、计算,结果进OPND栈
Pop_ch(OPTR,theta);
Pop_f(OPND,b);
Pop_f(OPND,a);
Push_f(OPND,Operate(a,theta,b));
break;
}
}
}
return GetTop_f(OPND);
}
void main(){
while(1){
cout<<"***********************请输入算术表达式,并以=结束******************************"<<endl;
float n;
n=EvaluateExpression();
cout<<n<<endl;
}
}
温馨提示:内容为网友见解,仅供参考
第1个回答  2010-07-12
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<cmath>
using namespace std;
/*操作数元素结构体*/
struct elem_N
{
float data;
elem_N *next;
};
/*运算符元素结构体*/
struct elem_T
{
char data;
elem_T *next;
};
/*操作数栈结构体*/
struct stack_N
{
elem_N *top;
int length;
};
/*运算符栈结构体*/
struct stack_T
{
elem_T *top;
int length;
};
/*置空操作数栈*/
void Init_stack_N(stack_N *S)
{
S->top=NULL;
S->length=0;
}
/*置空运算符栈*/
void Init_stack_T(stack_T *S)
{
S->top=NULL;
S->length=0;
}
/*入操作数栈*/
void Push_N(stack_N *S,float e)
{
elem_N *p;
p=new elem_N;
if(!p)exit(0);
p->data=e;
p->next=S->top;
S->top=p;
S->length++;
}
/*入运算符栈*/
void Push_T(stack_T *S,char e)
{
elem_T *p;
p=new elem_T;
if(!p)exit(0);
p->data=e;
p->next=S->top;
S->top=p;
S->length++;
}
/*出操作数栈*/
float Pop_N(stack_N *S)
{
elem_N *p;
if(S->top==NULL) return -1;
float e;
p=S->top;
e=p->data;
S->top=p->next;
S->length--;
delete p;
return e;
}
/*出运算符栈*/
char Pop_T(stack_T *S)
{
elem_T *p;
if(S->top==NULL) return -1;
char e;
p=S->top;
e=p->data;
S->top=p->next;
S->length--;
delete p;
return e;
}
/*运算*/
float Operate(float a,char c,float b){
float s;
switch(c)
{
case '+':s=a+b; break;
case '-':s=a-b; break;
case '*':s=a*b; break;
case '/':if(b!=0) s=a/b;
else cout<<"error!\n";break;
default:cout<<"error!\n";
}
return s;
}
/*返回操作数栈栈顶元素*/
float Get_top_N(stack_N *S)
{
if(S->top==NULL) return -1;
float e;
e=S->top->data;
return e;
}
/*返回运算符栈栈顶元素*/
char Get_top_T(stack_T *S)
{
if(S->top==NULL) return -1;
char e;
e=S->top->data;
return e;
}
/*判断字符是否为运算符*/
int In(char c)
{
if(c!='+'&&c!='-'&&c!='*'&&c!='/'&&c!='('&&c!=')'&&c!='#')
return 1;
else return 0;
}
/*比较两运算符优先关系*/
char Precede(char a,char b)
{
int p=0,q=0;
char m[8]="+-*/()#";
char n[8][8]={">><<<>>",">><<<>>",">>>><>>",">>>><>>","<<<<<= ",">>>> >>","<<<< ="};
while(m[p]!=a)p++;
while(m[q]!=b)q++;
return(n[p][q]);
}
/*主函数*/
int main()
{
cout<<"====================================\n";
cout<<"== 本程序可进行浮点数加减乘除运算 ==\n";
cout<<"====================================\n";
char c,x,theta;
float a,b,e;
int i;
stack_T OPTR;//运算符栈
stack_N OPND;//操作数栈
Init_stack_T(&OPTR);
Push_T(&OPTR,'#');
Init_stack_N(&OPND);
cout<<"请输入表达式(以#结束):\n例如: 3.25*(45.9+54.1)/5#\n";
c=getchar();
while(c!='#'||Get_top_T(&OPTR)!='#')
{
if(In(c))//不是运算符则进操作数栈
{
e=c-'0';
Push_N(&OPND,e);
c=getchar();
/*以下是判断输入的是操作数还是运算符,直至操作数各位输入完毕*/
/*实现浮点数运算*/
while(In(c)&&c!='.')
{
a=Pop_N(&OPND);
a=a*10.0+(c-'0');
Push_N(&OPND,a);
c=getchar();
}
if(c=='.')//小数点后输入
{
c=getchar();
i=1;
while(In(c))
{
a=Pop_N(&OPND);
a=a+(c-'0')*pow(0.1,i);
Push_N(&OPND,a);
c=getchar();
i++;
}
}
/*以上是判断输入的是操作数还是运算符,直至操作数各位输入完毕*/
/*实现浮点数运算*/
}
else
{
switch(Precede(Get_top_T(&OPTR),c))
{
case'<':Push_T(&OPTR,c);c=getchar();break;//操作数栈栈顶元素优先权低
case'=':x=Pop_T(&OPTR);c=getchar();break;//脱挂号并接受下一字符
case'>':theta=Pop_T(&OPTR);b=Pop_N(&OPND);a=Pop_N(&OPND);
Push_N(&OPND,Operate(a,theta,b));break;//退栈并将运算结果入操作数栈

}
}
}
cout<<"\a="<<Get_top_N(&OPND)<<endl;//输出结果
return 0;
}
第2个回答  2010-07-01
(1+1-1*1/1)=1
第3个回答  2010-07-08
//头文件
#include<cassert>
using namespace std;
template<typename T>class Stack;
template<typename T>class Node{
T info;
Node<T>*link;
public:
Node(T data=0,Node<T>*next=NULL){
info=data;
link=next;
}
friend class Stack<T>;
};
template<typename T>class Stack{
Node<T>*top;
public:
Stack(){top=NULL;}
~Stack();
void Push(const T&data);
T Pop();
T GetTop();
void MakeEmpty();
bool IsEmpty(){return top==NULL;}
};
template<typename T>Stack<T>::~Stack(){MakeEmpty();}
template<typename T>void Stack<T>::MakeEmpty(){
Node<T>*temp;
while(top!=NULL){
temp=top;
top=top->link;
delete temp;
}
}
template<typename T>void Stack<T>::Push(const T&data){
top=new Node<T>(data,top);
}
template<typename T>T Stack<T>::Pop(){
assert(!IsEmpty());
Node<T>*temp=top;
T data=temp->info;
top=top->link;
delete temp;
return data;
}
template<typename T>T Stack<T>::GetTop(){
assert(!IsEmpty());
return top->info;
}
main函数

#include<iostream>
#include<cstring>
#include<string>
#include<cstdlib>
#include"Ex7_1.h"
using namespace std;
class Calculator{
Stack<double>Nstack;
Stack<char>Ostack;
public:
Calculator(void){};
double myatoi(char str[]);
double Cal(string& str1);
void GetTwoNum(double&Num1,double &Num2);
double Compute(char Opr);
void Clear(void);
};
void Calculator::Clear(){
Nstack.MakeEmpty();
Ostack.MakeEmpty();
}
double Calculator::myatoi(char str[]){
int i,j,k;
double a=0,b=0;
i=strlen(str);
for(j=0;j<i;j++){if(str[j]=='.')break;}
if(j==i-1)return atoi(str);
else {
for(k=j-1;k>-1;k--)a=(str[k]-'0')+10*a;
for(k=i-1;k>j;k--)b=double(str[k]-'0')/10+b/10;
return a+b;
}
} //转化函数
void Calculator::GetTwoNum(double &Num1,double &Num2){
Num1=Nstack.Pop();
Num2=Nstack.Pop();
}
double Calculator::Compute(char Opr){
double Num1,Num2;
if(Opr!='='&&Opr!=')')GetTwoNum(Num1,Num2);
switch(Opr){
default:return 0;
case '+':Nstack.Push(Num2+Num1);return 0;break;
case '-':Nstack.Push(Num2-Num1);return 0;break;
case '*':Nstack.Push(Num2*Num1);return 0;break;
case '/':Nstack.Push(Num2/Num1);return 0;break;
case ')':return Nstack.Pop();break;
case '=':return Nstack.Pop();cout<<Nstack.Pop()<<endl;break;
}
}
double Calculator::Cal(string&str1){
bool b1=true,b2=true;
char ch1,ch2;
char str[50];
int k=-1,counter=-1;
while(b2){
counter++; //输入到第几个字符
ch1=str1[counter];
if((ch1>='0'&&ch1<='9')||ch1=='.'){
k++;
str[k]=ch1;
}
else{
if((k>=0&&ch1!='(')||ch1=='='||ch1==')'||ch1=='+'||ch1=='-'||ch1=='*'||ch1=='/'){
if(k>=0){str[k+1]='\0';
Nstack.Push(myatoi(str));
k=-1;
}
switch(ch1){
default:return 1;
case 'c':Clear();break;
case '+':
case '-':
while(!Ostack.IsEmpty()){
ch2=Ostack.Pop();
Compute(ch2);
}
Ostack.Push(ch1);
break;
case '*':
case '/':
while(!Ostack.IsEmpty()&&b1){
ch2=Ostack.Pop();
if(ch2=='*'||ch2=='/')
Compute(ch2);
else{
Ostack.Push(ch2);
b1=false;
}
}
Ostack.Push(ch1);
b1=true;
break;
case '=':
case ')':
while(!Ostack.IsEmpty()){
ch2=Ostack.Pop();
Compute(ch2);
}
str1.erase(0,counter);
return Compute(ch1);
break;
}
}
if(ch1=='('){str1.erase(0,counter+1);Calculator cal;Nstack.Push(cal.Cal(str1));counter=0;}
}
}
return 0;
}
int main(){
Calculator cal;
cout<<"请输入四则运算式:"<<endl;
while(1){
string str;
cin>>str;
if(str=="z")break;
double result=cal.Cal(str);
cout<<result<<endl;
}
return 0;
}
第4个回答  2010-07-07
给你写个简单的吧,哈哈一定要给分啊!==哦

(C++) 输入一个由数字、+、-、*、\/及括号组成的自述表达式,求其值。
typedef char SElemType_ch;typedef int Status;include<iostream.h> include<stdlib.h> \/*free()头文件 *\/ define OK 1 define ERROR 0 typedef struct SqStack_f{ \/* 运算数栈 *\/ SElemType_f *base; \/* 在栈构造之前和销毁之后,base的值为NULL *\/ SElemType_f *top; \/* 栈...

C++输入表达式,求值
法运算符“*”,且没有括号,所有参与运算的数字均为 0 到 2^31-1 之间的整数。输入数据保 证这一行只有 0~ 9、+、*这 12 种字符。输出格式:输出只有一行,包含一个整数,表示这个表达式的值。注意:当答案长度多于 4 位时,请只输出最后 4 位,前导 0 不输出。include <iostream>#includ...

用c++做一个四则运算计算器(支持加减乘除混合运算,支持括号,倒数,正负...
op.pop(); } } return dealNum(num1, num2, op1);}int main() { while (1) { \/\/循环输入,结束直接关闭即可 string my; cout << "输入算式: " << endl; getline(cin, my); dealString(my); cout << "结果为: " << cal() << endl << endl; }}———版...

C++表达求值
printf("请输入表达式%d: ", i);scanf("%s", pexpr + 101*i);char* p = pexpr + 101*i;float paramA = 0;float paramB = 0;char opertmp = ' ';char oper = ' ';while(1){ int ret = sscanf(p, "%f%c", ¶mB, &opertmp);p = strchr(p, opertmp) + 1;if ...

算数表达式求值c++
1. 只考虑 + - * \/ ( ) 这几个基本运算符,且是二元操作 2. 运算数只考虑 0-9,这10个简单的数,方便从string中取出来 3. 输入的表达式没有语法错误 【背景知识】 中缀表示法(Infix expression):操作符位于两个操作数中间,算术表达式的常规表示法。只用于二元操作符的情况,而且需要用括号和优先规则排除多义...

C或C++高手进从1到13中任选4个数,运用+,-,*,\/,()使其最后的值为24,这...
如( ( ( 1 + 2 ) + 3 ) * 4 ) = 24 和 ( ( 1 + ( 2 + 3 ) ) * 4 ) = 24去掉不必要的括号和,都能化成:(1 + 2 + 3 )*4 = 24 ,因此一般我们认为上面这两个式子是相同的。 *\/#include <iostream>#include <cstring>#include <cmath>#include <string>#include <ctime>#include...

...读入并计算一个只包含加减运算的表达式,每个输入的数据都是浮点数...
中缀转后缀表达式,然后对后缀表达式求值就可以了,这样不仅可以包含加减,还可以包含乘除括号、平方、开方等等

C语言 在一个数组或指针里有一个算式(字符串),如何对它求值?
如果当前元素是右括号")"则栈顶元素依此出栈,直至与它匹配的左括号"("出栈为止。对后缀表达式进行计算原理是这样的:对后缀表达式由左往右方向进行扫描,遇到数字则进栈,遇到运算符号则在栈里依此出栈两组数字进行计算,计算结果依然进栈,反复此操作。最后栈底部最后一个元素就是该表达式的运算结果。

如何用C++编写个程序中缀表达式变成后缀表达式,并用后缀表达式求值
cout<<"括号没有配对!"<<endl; goto start; } } if(strcmp(str,"exit")==0) break; \/\/如果输入的是exit就退出 unsigned int temp=strlen(str),k=0; \/\/把原始算式的长度存在temp里,标记k指向第一个字符 if(isdigit(str[0])) s='n'; else s='s'; \/\/判断第一个字符是数字还是符号 for...

输入一个带有括号的四则运算的算式,以#结束,输出该算式结果(用c++实现...
_tag;va_list list;va_start(list, _tag);if (tag == true)v.va = va_arg(list, double);else v.op = va_arg(list, int);}};double calc(char *s){stack<vas> temp;stack<vas> res;char c;double v1, v2;while ((c = *s) != '#'){if ((c <= '9'&&c >= '...

相似回答