输入一组单字符变量名及其对应数值存入线性表,再输入一个关于这些变量的四则运算表达式,代入其数值计算表达式的最终结果并显示。
设计要求:
1.单字符变量名与取值必须成对输入某结构体元素,再建立这些元素构成的线性表。
2.变量名与取值输入后立即显示变量信息,如“A=3,B=6,……”。
3.四则运算表达式必须以一个完整的字符串输入后,计算得出最终结果并显示。比如,运行阶段“(A+B)*3 回车”后,换行显示“=27”。
4.思考:若为四则运算增添函数计算功能,使其支持绝对值函数abs()、平方根函数sqr()、较大值函数max()、较小值函数min()等,表达式如A+abs(C+D)+max(E,F),应如何处理整个计算过程?
代码:
#include<stdio.h>
#include<string.h>
#define Size 30
#define OK 1
#define ERROR 0
typedef struct
{
char elem;
int data;
}sqlist;//定义一个线性表储存变量值
sqlist arr[Size];
typedef struct stack
{
char data[Size];
int top;
}sqstack;
栈的基本操作
void Inition(sqstack* s)//初始化栈
{
s->top = -1;
}
void push(sqstack* s, char elem)//入栈
{
s->top++;
s->data[s->top] = elem;
}
char pop(sqstack* s)//出栈
{
return s->data[s->top--];
}
比较运算符优先级
int Judge(char a, char b)
{
//判断两个运算符优先级
int value1, value2;
value1 = value2 = 0;
switch (a)
{
case '(':value1 = 1; break;
case '+':value1 = 3; break;
case '-':value1 = 3; break;
case '*':value1 = 5; break;
case '/':value1 = 5; break;
case '^':value1 = 7; break;
case ')':value1 = 9; break;
}
switch (b)
{
case '(':value2 = 1; break;
case '+':value2 = 3; break;
case '-':value2 = 3; break;
case '*':value2 = 5; break;
case '/':value2 = 5; break;
case '^':value2 = 7; break;
case ')':value2 = 9; break;
}
//优先级a<b则ERROR
if (value1 <= value2)
return ERROR;
else
return OK;
}
后缀表达式求值
int SuffixValue(sqstack* s1, sqstack* s2)//后缀表达式求值
{
int e;
while (s1->top > -1)
{
push(s2, pop(s1));//转出后缀表达式
}
while (s2->top > -1)
{
while (s2->data[s2->top] >= 0 && s2->data[s2->top] <= 9)
{
push(s1, pop(s2));
}
if (s2->data[s2->top] == '+')
{
(s2->top)--;
e = pop(s1) + pop(s1);
push(s1, e);
}
else if (s2->data[s2->top] == '-')
{
(s2->top)--;
e = pop(s1);
push(s1, pop(s1) - e);
}
else if (s2->data[s2->top] == '*')
{
(s2->top)--;
e = pop(s1) * pop(s1);
push(s1, e);
}
else if (s2->data[s2->top] == '/')
{
(s2->top)--;
e = pop(s1);
push(s1, pop(s1) / e);
}
}
return s1->data[s1->top];//返回最终计算结果
}
主函数实现将算式表达式转化成操作数和运算符,放入栈中,完成中缀转后缀。
int main()
{
sqstack* opt=(sqstack*)malloc(sizeof(sqstack));
sqstack* exp=(sqstack*)malloc(sizeof(sqstack));//申请内存
char str[Size];
int value;
int k=0;
int a,flag;
flag=0;
Inition(opt);
Inition(exp);
printf("往线性表里输入数据\n");
for(;k<Size;k++)
{
scanf(" %c %d", &arr[k].elem, &arr[k].data);
printf("%c=%d\n", arr[k].elem, arr[k].data);
printf("输入1继续输数据");
scanf("%d",&a);
if(a!=1)
{
printf("跳出循环\n");
break;
}
}
printf("输入一个表达式\n");
scanf("%s", str);
for (int i = 0; i < strlen(str); i++)
{
for (int j = 0; j < Size; j++)
{
if (str[i] == arr[j].elem)
{
str[i] = arr[j].data;//给表达式里的变量赋值
break;
}
}
}
for (int i = 0; i < strlen(str); i++)
{
if (str[i] == '(')
push(exp, str[i]);
else if (str[i] >= 0 && str[i] <= 9)
push(opt, str[i]);//操作数直接进栈
else if (str[i] == ')')
{
do
{
if(exp->data[exp->top] != '(')
push(opt,pop(exp));
else
{
exp->top--;//括号不能进opt栈
flag=1;
}
}while(flag==0);
}
else
{
if (Judge(str[i], exp->data[exp->top]) == 0)
{
push(opt, pop(exp));
break;
}
if (Judge(str[i], exp->data[exp->top]) == 1)
{
push(exp, str[i]);
}
}
}
while (exp->top >= 0)
{
push(opt, pop(exp));
}//清空exp栈
value = SuffixValue(opt, exp);
printf("表达式的值:\n");
printf("%d\n", value);
}