求算数表达式的值

编写算法,要求在键盘上输入一个算术表达式6+(7-1)*3+10/2, 输出表达式的值。

【分析】

表达式求值是栈的典型应用,计算机在求算术表达式的值分为两步:
(1)将中缀表达式转换为后缀表达式; (2) 依据后缀表达式计算表达式的值。

6+(7-1)*3+10/2的后缀表达式为671-3*+ 102/+,后缀表达式中不存在括号,并且操作数顺序保持不变,每输出两个操作数,输出一一个运算符,再进行运算。671-3*+ 102/ +的运算过程为:

(1)先输出7和1,然后计算7-1,得到6,后缀表达式为663*+ 102/+。
(2) 输出6和3,计算6*3,得到18, 后缀表达式为618+ 102/+。
(3)输出6和18,计算6+18,得到24,后缀表达式为24102/+。
(4)输出10和2,计算10/2, 得到5,后缀表达式为245+。
(5)输出24和5,计算24+5, 得到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*/
}

结果:

猜你喜欢

转载自blog.csdn.net/baidu_36669549/article/details/104160548