Find the value of an arithmetic expression

To write an algorithm, it is required to input an arithmetic expression 6+(7-1)*3+10/2 on the keyboard and output the value of the expression.

【analysis】

Expression evaluation is a typical application of the stack. The computer is divided into two steps in calculating the value of an arithmetic expression:
(1) Convert the infix expression to a postfix expression; (2) Calculate the value of the expression based on the postfix expression.

The suffix expression of 6+(7-1)*3+10/2 is 671-3*+ 102/+. There are no parentheses in the suffix expression, and the order of the operands remains unchanged. Every two operands are output, Output an operator, and then perform the operation. The calculation process of 671-3*+ 102/ + is:

(1) First output 7 and 1, then calculate 7-1 to get 6, and the suffix expression is 663*+ 102/+.
(2) Output 6 and 3, calculate 6*3, get 18, and the suffix expression is 618+102/+.
(3) Output 6 and 18, calculate 6+18, get 24, and the suffix expression is 24102/+.
(4) Output 10 and 2, calculate 10/2, get 5, and the suffix expression is 245+.
(5) Output 24 and 5, calculate 24+5, and get 29.

code:

main.cpp

/*包含头文件*/
#include<stdio.h>
#include<string.h>
#include <iostream>
/*包含顺序栈基本操作实现函数*/
typedef char DataType;
#include"SeqStack.h"
#define MAXSIZE 50
/*操作数栈定义*/
typedef struct
{
	float data[MAXSIZE];
	int top;
}OpStack;
/*函数声明*/
void TranslateExpress(char s1[], char s2[]);
float ComputeExpress(char s[]);
void main()
{
	char a[MAXSIZE], b[MAXSIZE];
	float f;
	printf("请输入一个算术表达式:\n");
	gets_s(a);
	printf("中缀表达式为:%s\n", a);
	TranslateExpress(a, b);
	printf("后缀表达式为:%s\n", b);
	f = ComputeExpress(b);
	printf("计算结果:%f\n", f);
	system("pause");
}
float ComputeExpress(char a[])
/*计算后缀表达式的值*/
{
	OpStack S; 				/*定义一个操作数栈*/
	int i = 0, value;
	float x1, x2;
	float result;
	S.top = -1; 					/*初始化栈*/
	while (a[i] != '\0') 				/*依次扫描后缀表达式中的每个字符*/
	{
		if (a[i] != ' '&&a[i] >= '0'&&a[i] <= '9') 	/*如果当前字符是数字字符*/
		{
			value = 0;
			while (a[i] != ' ') 				/*如果不是空格,说明数字字符是两位数以上的数字字符*/
			{
				value = 10 * value + a[i] - '0';
				i++;
			}
			S.top++;
			S.data[S.top] = value; 		/*处理之后将数字进栈*/
		}
		else							/*如果当前字符是运算符*/
		{
			switch (a[i]) 				/*将栈中的数字出栈两次,然后用当前的运算符进行运算,再将结果入栈*/
			{
			case '+':
				x1 = S.data[S.top];
				S.top--;
				x2 = S.data[S.top];
				S.top--;
				result = x1 + x2;
				S.top++;
				S.data[S.top] = result;
				break;
			case '-':
				x1 = S.data[S.top];
				S.top--;
				x2 = S.data[S.top];
				S.top--;
				result = x2 - x1;
				S.top++;
				S.data[S.top] = result;
				break;
			case '*':
				x1 = S.data[S.top];
				S.top--;
				x2 = S.data[S.top];
				S.top--;
				result = x1*x2;
				S.top++;
				S.data[S.top] = result;
				break;
			case '/':
				x1 = S.data[S.top];
				S.top--;
				x2 = S.data[S.top];
				S.top--;
				result = x2 / x1;
				S.top++;
				S.data[S.top] = result;
				break;
			}
			i++;
		}
	}
	if (!S.top != -1)						/*如果栈不空,将结果出栈,并返回*/
	{
		result = S.data[S.top];
		S.top--;
		if (S.top == -1)
			return result;
		else
		{
			printf("表达式错误");
			exit(-1);
		}
	}
}
void TranslateExpress(char str[], char exp[])
/*把中缀表达式转换为后缀表达式*/
{
	SeqStack S; 				/*定义一个栈,用于存放运算符*/
	char ch;
	DataType e;
	int i = 0, j = 0;
	InitStack(&S);
	ch = str[i];
	i++;
	while (ch != '\0')				/*依次扫描中缀表达式中的每个字符*/
	{
		switch (ch)
		{
		case'(': 				/*如果当前字符是左括号,则将其进栈*/
			PushStack(&S, ch);
			break;
		case')': 				/*如果是右括号,将栈中的操作数出栈,并将其存入数组exp中*/
			while (GetTop(S, &e) && e != '(')
			{
				PopStack(&S, &e);
				exp[j] = e;
				j++;
			}
			PopStack(&S, &e);	/*将左括号出栈*/
			break;
		case'+':
		case'-': 				/*如果遇到的是'+'和'-',因为其优先级低于栈顶运算符的优先级,所以先将栈顶字符出栈,并将其存入数组exp中,然后将当前运算符进栈*/
			while (!StackEmpty(S) && GetTop(S, &e) && e != '(')
			{
				PopStack(&S, &e);
				exp[j] = e;
				j++;
			}
			PushStack(&S, ch);	/*当前运算符进栈*/
			break;
		case'*': 				/*如果遇到的是'*'和'/',先将同级运算符出栈,并存入数组exp中,然后将当前的运算符进栈*/
		case'/':
			while (!StackEmpty(S) && GetTop(S, &e) && e == '/' || e == '*')
			{
				PopStack(&S, &e);
				exp[j] = e;
				j++;
			}
			PushStack(&S, ch);	/*当前运算符进栈*/
			break;
		case' ': 				/*如果遇到空格,忽略*/
			break;
		default: 				/*如果遇到的是操作数,则将操作数直接送入数组exp中,并在其后添加一个空格,用来分隔数字字符*/
			while (ch >= '0'&&ch <= '9')
			{
				exp[j] = ch;
				j++;
				ch = str[i];
				i++;
			}
			i--;
			exp[j] = ' ';
			j++;
		}
		ch = str[i];				/*读入下一个字符,准备处理*/
		i++;
	}
	while (!StackEmpty(S)) 		/*将栈中所有剩余的运算符出栈,送入数组exp中*/
	{
		PopStack(&S, &e);
		exp[j] = e;
		j++;
	}
	exp[j] = '\0';
}


SeqStack.h

#define STACKSIZE 100
typedef struct
{
    DataType stack[STACKSIZE];
    int top;
}SeqStack;
void InitStack(SeqStack *S)    
/*将栈S初始化为空栈*/
{
	S->top=0;	/*把栈顶指针置为0*/
}
int StackEmpty(SeqStack S)   
/*判断栈是否为空,栈为空返回1,否则返回0*/
{
    if(S.top==0)			/*当栈为空时*/
        return 1;			/*返回1*/
    else					/*否则*/
        return 0; 			/*返回0*/
}
int GetTop(SeqStack S, DataType *e)   
/*取栈顶元素。将栈顶元素值返回给e,并返回1表示成功;否则返回0表示失败。*/
{
	if(S.top<=0)		/*在取栈顶元素之前,判断栈是否为空*/
	{
		printf("栈已经空!\n");
		return 0;
	}
	else
	{
		*e=S.stack[S.top-1];	/*取栈顶元素*/
		return 1;
	}
}
int PushStack(SeqStack *S,DataType e)   
/*将元素e进栈,元素进栈成功返回1,否则返回0.*/
{
	if(S->top>=STACKSIZE)				/*在元素进栈前,判断是否栈已经满*/
	{
        printf("栈已满,不能进栈!\n");
        return 0;
	}
	else
	{
        S->stack[S->top]=e;			/*元素e进栈*/
        S->top++;					/*修改栈顶指针*/
        return 1;
	}
}
int PopStack(SeqStack *S,DataType *e)
/*出栈操作。将栈顶元素出栈,并将其赋值给e。出栈成功返回1,否则返回0*/
{
    if(S->top==0)		/*元素出栈之前,判断栈是否为空*/
    {
        printf("栈已经没有元素,不能出栈!\n");
        return 0;
    }
    else
	{
		S->top--;			/*先修改栈顶指针,即出栈*/
        *e=S->stack[S->top];	/*将出栈元素赋值给e*/
        return 1;
    }
}

int StackLength(SeqStack S)
/*求栈的长度,即栈中元素个数,栈顶指针的值就等于栈中元素的个数*/
{
    return S.top;
}

void ClearStack(SeqStack *S)    
/*清空栈*/
{
	S->top=0;			/*将栈顶指针置为0*/
}

result:

 

Guess you like

Origin blog.csdn.net/baidu_36669549/article/details/104160548