栈 2

来源:互联网 发布:淘宝怎么做汽车配件 编辑:程序博客网 时间:2024/05/20 14:41
/*
题目1019:简单计算器
题目描述:
    读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
输入:
    测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。
输出:
    对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
样例输入:
1 + 2
4 + 2 * 5 - 7 / 11
0
样例输出:
3.00
13.36      for ====>错误写成int
*/
#include <stack>
#include <stdio.h>
using namespace std;
char str[220]; //保存表达式字符串
int mat[][5] = {//优先级矩阵,若mat[i][j] == 1,则表示i号运算符优先级大于j号运算符,运算符编码规则为+为1号,-为2号,*为3号,/为4号,我们人为添加在表达式首尾的标记运算符为0号
1,0,0,0,0,
1,0,0,0,0,
1,0,0,0,0,
1,1,1,0,0,
1,1,1,0,0,
};
stack<int> op; //运算符栈,保存运算符编号
stack<double> in;//数字栈,运算结果可能存在浮点数,所以保存元素为double
void getop(bool &reto, int &retn, int &i){
//获得表达式中下一个元素函数,若函数运行结束时,引用变量reto为true,则表示该元素为一个运算符,其编号保存在引用变量retn中,否则,表示该元素为一个数字,其值保存在引用变量retn中,引用变量i表示遍历到的字符串下标
if(i == 0 && op.empty() == true){//若此时遍历字符串第一个字符,且运算符栈为空,我们人为添加编号为0的标记字符
 reto = true;//为运算符
 retn = 0;//编号为0
 return;//返回
}
if(str[i] == 0){//若此时遍历字符为空字符,则表示字符串已经被遍历完
  reto = true; //返回为运算符
  retn = 0; //编号为0的标记字符
  return;//返回


}
if(str[i] >= '0' && str[i] <= '9'){//若当前字符为数字
  reto = false; //返回为数字
}
else{//否则
reto = true; //返回为运算符
if(str[i] == '+'){// 加号返回1
   retn = 1;
}
else if (str[i] == '-'){//减号返回2
   retn = 2;


}
else if(str[i] == '*'){//乘号返回3
   retn = 3;
}
else if(str[i] == '/'){//除号返回4
   retn = 4;
}
 i += 2;//i递增,跳过该运算字符和该运算字符后的空格
 return;//返回


}
 retn = 0;//返回结果为数字
 for(;str[i] != ' ' && str[i] != 0;i++){
//若字符串未被遍历完,且下一个字符不是空格,则依次遍历其后数字,
//计算当前连续数字字符表示的数值
 retn *= 10;
 retn += str[i] - '0';
}//计算该数字的数字值
if(str[i] == ' ')//若其后字符为空格,则表示字符串未被遍历完
 i++; //i递增,跳过该空格
 return;//返回
}
int main(){
 while(gets(str)){//输入字符串,当其位于文件尾时,gets返回0
  if(str[0] == '0' && str[1] == 0) break;
 //若输入只有一个0,则退出
 bool retop; int retnum; //定义函数所需的引用变量
 int idx = 0;//定义遍历到的字符串下标,初始值为0
 while(!op.empty()) op.pop();
 while(!in.empty()) in.pop();//清空数字栈和运算符栈
 while(true){//循环遍历表达式字符串
  getop(retop,retnum,idx); //获取表达式中下一个元素
  if(retop == false){//若该元素为数字
    in.push((double)retnum);//将其压入数字栈中


}
else{//否则
double tmp;
if(op.empty() == true || mat[retnum][op.top()] == 1){
   op.push(retnum);
}//若运算符堆栈为空或者当前遍历到的运算符优先级大于栈顶运算符,将
//该运算符压入运算符堆栈
else {//否则
 while(mat[retnum][op.top()]==0){
//只要当前运算符优先级小于栈顶元素运算符,则重复循环
  int ret = op.top();//保存栈顶运算符
  op.pop();//弹出
  double b = in.top();
  in.pop();
  double a = in.top();
  in.pop(); //从数字堆栈栈顶弹出两个数字,依次保存在遍历a,b中
  if(ret == 1) tmp = a+b;
  else if(ret == 2) tmp = a-b;
  else if(ret == 3) tmp = a*b;
  else tmp = a/b; //按照运算符类型完成运算
  in.push(tmp); //将结果压回数字堆栈
}
  op.push(retnum);//将当前运算符压入运算符堆栈
}
}
  if(op.size() == 2 && op.top() == 0) break;
//若运算符堆栈只有两个元素,且其栈顶元素为标记运算符,则表示表达式求值
//结束
}
printf("%.2f\n",in.top());//输出数字栈中唯一的数字,即为答案
}
  return 0;
}


#include "stdio.h"
#include "string.h"
#define MAX 1001
 
double stack[MAX];
int tail;
 
int main(){
  int a;
  while(scanf("%d ",&a)&&a!=0){  //scanf 空格也需要注意
   tail=0;
   stack[++tail]=1.0*a;//tail始终指向末尾数字位置
   char ch1,ch2;
   while(scanf("%c %d%c",&ch1,&a,&ch2)!=EOF){ //scanf空格也需要注意
    if(ch1=='+'){
     stack[++tail]=1.0*a;//push
    }else if(ch1=='-'){
     stack[++tail]=-1.0*a;//push neg
    }else if(ch1=='*'){
     stack[tail]=stack[tail]*a;//update tail
    }else if(ch1=='/'){
     stack[tail]=stack[tail]/(double)a;//updata tail
    }
    if(ch2!=' ')break; 
  }
  double result=0;
  for(int i=1;i<=tail;i++)result+=stack[i];
  printf("%.2lf\n",result);
  }
return 1;
}
0 0
原创粉丝点击