用c语言编写代码,实现使用算符优先分析方法设计一个计算器,必须能够完成加、减、乘、除、幂、括号()等运算符;给定任意符号串,判断其是否是正确的表达式,若是给出计算结果。给出具体代码
时间: 2023-09-20 22:06:16 浏览: 113
设计一个模拟计算器的程序,要求能对包含加、减、乘、除、括号运算符及
### 回答1:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define MAXSIZE 100
#define ERROR 0
#define OK 1
#define TRUE 1
#define FALSE 0typedef int Status;
typedef char SElemType;typedef struct
{
SElemType data[MAXSIZE];
int top;
}SqStack;// 初始化
Status InitStack(SqStack *S)
{
S->top = -1;
return OK;
}// 进栈
Status Push(SqStack *S, SElemType e)
{
if (S->top == MAXSIZE - 1)
{
return ERROR;
}
S->top++;
S->data[S->top] = e;
return OK;
}// 出栈
Status Pop(SqStack *S, SElemType *e)
{
if (S->top == -1)
{
return ERROR;
}
*e = S->data[S->top];
S->top--;
return OK;
}// 判断栈是否为空
Status StackEmpty(SqStack S)
{
if (S.top == -1)
{
return TRUE;
}
else
{
return FALSE;
}
}// 返回栈顶元素
Status GetTop(SqStack S, SElemType *e)
{
if (S.top == -1)
{
return ERROR;
}
*e = S.data[S.top];
return OK;
}// 返回优先级
int Precede(SElemType a, SElemType b)
{
switch (a)
{
case '#':
if (b == '#')
return 0;
else
return -1;
case '(':
if (b == '#' || b == ')')
return 1;
else
return -1;
case '*':
case '/':
if (b == '#' || b == '(' || b == '+' || b == '-')
return 1;
else
return -1;
case '+':
case '-':
if (b == '#' || b == '(')
return 1;
else
return -1;
case ')':
if (b == '#')
return 1;
else
return -1;
default:
return -1;
}
}// 运算
int Operate(int a, int b, SElemType c)
{
switch (c)
{
case '+':
return a + b;
case '-':
return a - b;
case '*':
return a * b;
case '/':
return a / b;
}
return 0;
}// 算符优先分析法
int EvaluateExpression(char exp[])
{
int i = 0;
int opnd1, opnd2, result;
SElemType c, theta;
SqStack OPTR, OPND;
InitStack(&OPTR);
Push(&OPTR, '#');
InitStack(&OPND);
c = exp[i++];
while (c != '#' || GetTop(OPTR, &theta) != '#')
{
if (!(theta == '(' || theta == '#') && (c == '(' || c == '#'))
{
Pop(&OPTR, &theta);
Pop(&OPND, &opnd2);
Pop(&OPND, &opnd1);
result = Operate(opnd1, opnd2, theta);
Push(&OPND, result);
}
else
{
while (Precede(theta, c) >= 0)
{
Pop(&OPTR, &theta);
Pop(&OPND, &opnd2);
Pop(&OPND, &opnd1);
result = Operate(opnd1, opnd2, theta);
Push(&OPND, result);
GetTop(OPTR, &theta);
}
Push(&OPTR, c);
c = exp[i++];
}
}
Pop(&OPND, &result);
return result;
}// 主函数
int main()
{
char exp[MAXSIZE];
int result; printf("请输入表达式:");
scanf("%s", exp);
result = EvaluateExpression(exp); printf("%s=%d\n", exp, result); return 0;
}
### 回答2:
以下是使用C语言编写的一个简单的算符优先分析方法设计的计算器代码。
```c
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define MAX 100 // 定义符号串的最大长度
typedef struct {
int top;
char data[MAX];
} Stack;
void initStack(Stack *s) {
s->top = -1;
}
void pushStack(Stack *s, char c) {
if (s->top >= MAX - 1) {
printf("栈已满\n");
exit(1);
} else {
s->data[++(s->top)] = c;
}
}
char popStack(Stack *s) {
if (s->top == -1) {
printf("栈为空\n");
exit(1);
} else {
return s->data[(s->top)--];
}
}
char getTop(Stack *s) {
if (s->top == -1) {
return '\0';
} else {
return s->data[s->top];
}
}
int isOperator(char c) {
return (c == '+' || c == '-' || c == '*' || c == '/' || c == '^' || c == '(' || c == ')');
}
int priority(char op) {
switch (op) {
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
case '^':
return 3;
case '(':
return 0;
default:
return -1;
}
}
double calculate(char op, double num1, double num2) {
switch (op) {
case '+':
return num1 + num2;
case '-':
return num1 - num2;
case '*':
return num1 * num2;
case '/':
return num1 / num2;
case '^':
return pow(num1, num2);
default:
return -1;
}
}
double evaluateExpression(char *expression) {
Stack numStack; // 数字栈
Stack opStack; // 操作符栈
initStack(&numStack);
pushStack(&opStack, '#');
int len = strlen(expression);
int i = 0;
while (i < len) {
char c = expression[i];
if (isdigit(c)) {
double num = 0;
while (i < len && isdigit(expression[i])) {
num = num * 10 + expression[i] - '0';
i++;
}
pushStack(&numStack, num);
} else if (isOperator(c)) {
char topOp = getTop(&opStack);
if (priority(c) > priority(topOp)) {
pushStack(&opStack, c);
i++;
} else {
double num2 = popStack(&numStack);
double num1 = popStack(&numStack);
char op = popStack(&opStack);
double result = calculate(op, num1, num2);
pushStack(&numStack, result);
}
} else if (c == ')') {
while (getTop(&opStack) != '(') {
double num2 = popStack(&numStack);
double num1 = popStack(&numStack);
char op = popStack(&opStack);
double result = calculate(op, num1, num2);
pushStack(&numStack, result);
}
popStack(&opStack);
i++;
} else if (c == ' ') {
i++;
} else {
printf("非法字符\n");
exit(1);
}
}
while (getTop(&opStack) != '#') {
double num2 = popStack(&numStack);
double num1 = popStack(&numStack);
char op = popStack(&opStack);
double result = calculate(op, num1, num2);
pushStack(&numStack, result);
}
return getTop(&numStack);
}
int main() {
char expression[MAX];
printf("输入一个符号串:");
fgets(expression, MAX, stdin);
// 删除换行符
if (expression[strlen(expression) - 1] == '\n') {
expression[strlen(expression) - 1] = '\0';
}
// 判断是否是正确的表达式
int valid = 1; // 默认为正确
for (int i = 0; i < strlen(expression); i++) {
if (!isdigit(expression[i]) && !isOperator(expression[i]) && expression[i] != ' ') {
valid = 0; // 包含非法字符
break;
}
}
if (valid) {
double result = evaluateExpression(expression);
printf("计算结果:%f\n", result);
} else {
printf("不是正确的表达式\n");
}
return 0;
}
```
使用时,输入一个符号串,程序会先判断该符号串是否是正确的表达式,如果是正确的表达式,则会给出计算结果。如果不是正确的表达式,则会输出"不是正确的表达式"。
### 回答3:
使用算符优先分析方法设计一个计算器可以通过构建算符优先矩阵,并利用栈来实现表达式的计算过程。
算符优先矩阵(Operator Precedence Matrix)如下:
+ - * / ^ ( ) $
+: > > < < < < > >
-: > > < < < < > >
*: > > > > < < > >
/: > > > > < < > >
^: > > > > > < > >
(: < < < < < < = X
): > > > > > X > >
$: < < < < < X < =
其中">"表示优先级高,"<"表示优先级低,"="表示相等,"X"表示错误。
下面给出用C语言编写的代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <ctype.h>
#include <math.h>
typedef struct {
int type; // 操作数类型:0表示数字,1表示运算符
union {
double num; // 操作数为数字时的值
char op; // 操作数为运算符时的值
};
} Operand;
typedef struct {
Operand *elems; // 操作数栈的数组指针
int top; // 操作数栈的栈顶指针
int max_size; // 操作数栈的最大容量
} OperandStack;
void initOperandStack(OperandStack *stack, int size) {
stack->elems = (Operand *)malloc(sizeof(Operand) * size);
stack->top = -1;
stack->max_size = size;
}
bool isOperandStackEmpty(OperandStack *stack) {
return stack->top == -1;
}
bool isOperandStackFull(OperandStack *stack) {
return stack->top == stack->max_size - 1;
}
void push(OperandStack *stack, Operand op) {
stack->top++;
stack->elems[stack->top] = op;
}
Operand pop(OperandStack *stack) {
Operand op = stack->elems[stack->top];
stack->top--;
return op;
}
Operand getTop(OperandStack *stack) {
return stack->elems[stack->top];
}
char getPrecedence(char op) {
switch(op) {
case '+':
case '-':
return '<';
case '*':
case '/':
return '>';
case '^':
return '>';
case '(':
return '<';
case ')':
return '>';
case '$':
return '<';
default:
return 'X';
}
}
double calculate(double a, double b, char op) {
switch(op) {
case '+':
return a + b;
case '-':
return a - b;
case '*':
return a * b;
case '/':
return a / b;
case '^':
return pow(a, b);
default:
return 0.0;
}
}
bool isDigit(char ch) {
return isdigit(ch) || ch == '.';
}
double evaluateExpression(const char *exp) {
OperandStack operandStack;
OperandStack operatorStack;
initOperandStack(&operandStack, strlen(exp));
initOperandStack(&operatorStack, strlen(exp));
push(&operatorStack, (Operand){.type = 1, .op = '$'}); // 在运算符栈底放置 $
int i = 0;
while(exp[i] != '\0') {
if(isOperandStackEmpty(&operandStack) && isDigit(exp[i])) {
double num = strtod(&exp[i], NULL);
int j = i;
while(isDigit(exp[j]))
j++;
i = j;
push(&operandStack, (Operand){.type = 0, .num = num});
} else {
char op = exp[i];
char top = getPrecedence(getTop(&operatorStack).op);
if(top == '>' && isDigit(op)) {
double num = strtod(&exp[i], NULL);
int j = i;
while(isDigit(exp[j]))
j++;
i = j;
push(&operandStack, (Operand){.type = 0, .num = num});
} else {
switch(top) {
case '<':
push(&operatorStack, (Operand){.type = 1, .op = op});
i++;
break;
case '=':
pop(&operatorStack);
i++;
break;
case '>': {
Operand b = pop(&operandStack);
Operand a = pop(&operandStack);
Operand oper = pop(&operatorStack);
if(oper.op == '$') {
return a.num;
} else {
double result = calculate(a.num, b.num, oper.op);
push(&operandStack, (Operand){.type = 0, .num = result});
}
break;
}
default:
return 0.0; // 错误的表达式
}
}
}
}
return 0.0; // 错误的表达式
}
int main() {
char exp[100];
printf("请输入一个表达式:");
scanf("%s", exp);
double result = evaluateExpression(exp);
if(result != 0.0) {
printf("表达式正确,计算结果为:%lf\n", result);
} else {
printf("表达式错误!\n");
}
return 0;
}
```
以上是一个简单的基于算符优先分析方法的计算器的C语言实现,通过读取用户输入的表达式字符串,判断其是否正确,并给出计算结果。
阅读全文