题目描述:
对于一个不存在括号的表达式进行计算
输入:
存在多种数据,每组数据一行,表达式不存在空格
输出:
输出结果
样例输入:
6/2+3+3*4
样例输出:
18
参考代码:
/*
题目信息不完整,虽然样例输入表达式中全为整型,结果也为整型,
但可能会出现输入,输出中均为浮点型
这里,代码1:默认输入为整型,输出为浮点型
代码2:表达式中也包含浮点型和括号,且表达式中无空格。
*/
代码1:
#include
#include
#include
#include
using namespace std;
#define N 1001
char str[N];
int OP[4][4] =
{0,0,0,0,
0,0,0,0,
1,1,0,0,
1,1,0,0};//+,-,*,/
int getOP(char c) {
if (c == '+') return 0;
else if (c == '-') return 1;
else if (c == '*') return 2;
else if (c == '/') return 3;
}
int main() {
while (scanf("%s", str) != EOF) {
int len = strlen(str);
int i = 0;
stack num;
stack op;
while (i < len) {
if (str[i] >= '0'&&str[i] <= '9') {
int cnt = 0;
while (str[i] != '\0'&&str[i] >= '0'&&str[i] <= '9') {
cnt++;
i++;
}
double sum = 0, ans = 1;
for (int j = cnt - 1; j >= 0; j--) {
sum += (str[i-1-j] - '0')*ans;
ans *= 10;
}
num.push(sum);
printf("*%d**%.2lf\n", cnt,num.top());
}
else {
char c = str[i++];
int idx = getOP(c);
if (op.empty()) {
op.push(c);
// printf("!!!%c\n", op.top());
}
else {
//如果运算过程中出现栈为空,应该将判断栈是否为空放在前面,否则会出现栈溢出现象
while(op.empty()==false && OP[getOP(op.top())][idx] == 1) {
char c2 = op.top();
op.pop();
//printf("&&&&&&\n");
double b = num.top();
num.pop();
double a = num.top();
num.pop();
double ret;
if (c2 == '+') {
ret = a + b;
}
else if (c2 == '-') {
ret = a - b;
}
else if (c2 == '*') {
ret = a*b;
}
else if (c2 == '/') {
ret = a / b;
}
num.push(ret);
// printf("!!!%lf\n", num.top());
}
op.push(c);
//printf("!!!%c\n", op.top());
}
}
}
while (!op.empty()) {
char c2 = op.top(); op.pop();
double b = num.top();
num.pop();
double a = num.top();
num.pop();
double ret;
if (c2 == '+') {
ret = a + b;
}
else if (c2 == '-') {
ret = a - b;
}
else if (c2 == '*') {
ret = a*b;
}
else if (c2 == '/') {
ret = a / b;
}
num.push(ret);
}
printf("%.2lf\n", num.top());
}
return 0;
}
代码2:
#include
#include
#include
#include
using namespace std;
#define N 10001
char str[N];
char buf[N];
double to_double(char s[]) {//可能有小数点,可能没有,实际上已将包含整型的转化了
double ret=0;
int L1 = strlen(s);
int mark = 0;
bool flag = false;
for (int i = 0; i < L1; i++) {
if (s[i] == '.') {
mark = i;
flag = true;
break;
}
}
int tmp;
//若没有小数点
if (flag == false) {
tmp= 1;
for (int i =L1-1; i >= 0; i--) {
ret = (s[i] - '0')*tmp;
tmp *= 10;
}
return ret;
}
//计算小数点前的
tmp = 1;
for (int i = mark-1; i >=0; i--) {
ret = (s[i] - '0')*tmp;
tmp *= 10;
}
//计算小数点后的
tmp = 1;
for (int i = mark + 1; i < L1; i++) {
ret = (s[i] - '0')*tmp;
tmp /= 10;
}
return ret;
}
int getOp(char c) {
if (c == '+')
return 1 ;
else if (c == '-')
return 2;
else if (c == '*')
return 3;
else if (c == '/')
return 4;
else if (c == '(')
return 5;
}
int op[6][6] = {
1,0,0,0,0,0,
1,0,0,0,0,0,
1,0,0,0,0,0,
1,1,1,0,0,0,
1,1,1,0,0,0,
1,1,1,1,1,1
};
double calculate(double a, double b,char c) {
if (c == '+')
return a + b;
else if (c == '-')
return a - b;
else if (c == '*')
return a *b;
else if (c == '/'&&b!=0)
return a /b;
}
int main() {
while (scanf("%s", str) != EOF) {
int start, end;
stack num;
stack cal;
int len = strlen(str);
for (int i = 0; i < len; i++) {
int flag1 = 0, flag2 = 0;
//记录数字段所在的位置
while ((str[i] >= '0'&&str[i] <= '9') || str[i] == '.') {
if (flag1 == 0) start = i;
flag1 = 1;
end = i++;
if (i >= len) flag2 = 1;
}
//对数字的处理
if (flag1 == 1) {
int cnt = 0;
for (int i = start; i <= end; i++) {
buf[cnt++] = str[i];
}
buf[cnt++] = '\0';
double tem = to_double(buf);
num.push(tem);
}
if (flag2) break;//若表达式只有一个数字是,便可直接退出,因此退出后要判断运算符栈是否为空
//对运算符的处理
if (cal.empty()) {
cal.push(str[i]);
}
else{
if (str[i] != ')') {
int flag = getOp(str[i]);
if (flag == 1) {
cal.push(str[i]);}
else {
char c1 = cal.top();
cal.pop(); cal.push(str[i]);
if (c1 != '(') {
double a1, b1;
b1 = num.top(); num.pop();
a1 = num.top(); num.pop();
a1 = calculate(a1, b1,c1);
num.push(a1);}}
}
}
}
while (!cal.empty()) {//
char c1 = cal.top(); cal.pop();
double a1, b1;
b1 = num.top(); num.pop();
a1 = num.top(); num.pop();
a1 = calculate(a1, b1, c1);
num.push(a1);
}
printf("%.6llf\n", num.top());
}
return 0;
}