用C语言实现字符串转表达式并计算结果

用C语言实现字符串转表达式并计算结果

原理:用栈操作将中缀表达式转换为后缀表达式,再将后缀表达式计算。(需要特别注意运算符的优先级)。
中缀转后缀:读到操作数时,将其放到输出中,操作符用栈保存,特别注意运算符的优先级。(详细原理可查阅资料)
后缀计算:将读到的操作数保存到栈,读到操作符时将栈中两个操作数出栈,并与该操作符进行运算,再将计算结果压栈,特别要注意需要做好错误处理。
注意:栈可分别建立一个数据栈和一个操作符栈。该程序支持小数 整数 科学计数法 ,运算符支持+ - * / 幂(^)需要其他操作可在此基础上添加。
需要详细说明可留言或评论区讨论。
代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define STACK_SIZE 512

typedef enum ElemDataType
{
   
    OPERATOR = 1,
    INT,
    DOUBLE,
    POINTER
} ElemDataType;

typedef struct StackElem
{
   
    ElemDataType type;
    union {
   
        char op;
        int i;
        double d;
        void *p;
    };
} ElemType;

ElemType elemFromOperator(char c)
{
   
    ElemType ret = {
   .type = OPERATOR, .op = c};
    return ret;
}

ElemType elemFromInt(int i)
{
   
    ElemType ret = {
   .type = INT, .i = i};
    return ret;
}

ElemType elemFromDouble(double d)
{
   
    ElemType ret = {
   .type = DOUBLE, .d = d};
    return ret;
}

ElemType elemFromPointer(void* p)
{
   
    ElemType ret = {
   .type = POINTER, .p = p};
    return ret;
}

// ADT: Expression
//==================================================================
typedef struct Expression
{
   
    int size;
    int capacity; // 容量
    ElemType *tokens;
} Expression;

void initExpression(Expression *pExpr)
{
   
    if (pExpr == NULL)
    {
   
        return;
    }
    pExpr->size = 0;
    pExpr->capacity = 10;
    pExpr->tokens = malloc(sizeof(ElemType) * pExpr->capacity);
}

// 扩容
void expandExpression(Expression *pExpr, int newCapcity)
{
   
    if (pExpr == NULL)
    {
   
        return;
    }
    if (newCapcity <= pExpr->capacity * 2)
    {
   
        newCapcity = pExpr->capacity * 2;
    }
    ElemType* newTokens = malloc(sizeof(ElemType) * newCapcity);
    memcpy(newTokens, pExpr->tokens, sizeof(ElemType) * pExpr->capacity);
    free(pExpr->tokens);
    pExpr->tokens = newTokens;
}

void appendToken(Expression *pExpr, ElemType elem)
{
   
    if (pExpr == NULL)
    {
   
        return;
    }
    if (pExpr->size == pExpr->capacity)
    {
   
        expandExpression(pExpr, 0);
    }
    pExpr->tokens[pExpr->size] = elem;
    pExpr->size ++;
}

void clearExpression(Expression *pExpr, ElemType type)
{
   
    if (pExpr == NULL)
    {
   
        return;
    }
    pExpr->size = 0;
}

void freeExpression(Expression *pExpr)
{
   
    if (pExpr == NULL || pExpr->tokens == NULL)
    {
   
        return;
    }
    free(pExpr->tokens);
    pExpr->tokens = NULL;
    pExpr->size = 0;
}

// ADT: Stack
//==================================================================
struct Stack
{
   
    ElemType datas[STACK_SIZE];
    int top;
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
下面是使用栈实现字符串表达式计算的代码,包括将中缀表达式换为后缀表达式计算后缀表达式两部分: ```c #include <stdio.h> #include <stdlib.h> #include <ctype.h> #define MAX_SIZE 100 typedef struct { int top; char data[MAX_SIZE]; } Stack; void push(Stack *s, char c) { if (s->top == MAX_SIZE - 1) { printf("Stack overflow!\n"); exit(1); } s->data[++s->top] = c; } char pop(Stack *s) { if (s->top == -1) { printf("Stack underflow!\n"); exit(1); } return s->data[s->top--]; } char peek(Stack *s) { if (s->top == -1) { printf("Stack underflow!\n"); exit(1); } return s->data[s->top]; } int is_empty(Stack *s) { return s->top == -1; } int is_operator(char c) { return c == '+' || c == '-' || c == '*' || c == '/' || c == '^'; } int precedence(char c) { switch (c) { case '+': case '-': return 1; case '*': case '/': return 2; case '^': return 3; default: return 0; } } void infix_to_postfix(char *infix, char *postfix) { Stack s; s.top = -1; int i, j; char c; for (i = 0, j = 0; infix[i] != '\0'; i++) { if (isdigit(infix[i])) { postfix[j++] = infix[i]; } else if (infix[i] == '(') { push(&s, infix[i]); } else if (infix[i] == ')') { while (!is_empty(&s) && (c = pop(&s)) != '(') { postfix[j++] = c; } if (c != '(') { printf("Mismatched parentheses!\n"); exit(1); } } else if (is_operator(infix[i])) { while (!is_empty(&s) && precedence(infix[i]) <= precedence(peek(&s))) { postfix[j++] = pop(&s); } push(&s, infix[i]); } else { printf("Invalid character in expression!\n"); exit(1); } } while (!is_empty(&s)) { c = pop(&s); if (c == '(') { printf("Mismatched parentheses!\n"); exit(1); } postfix[j++] = c; } postfix[j] = '\0'; } double evaluate_postfix(char *postfix) { Stack s; s.top = -1; int i; char c; double a, b; for (i = 0; postfix[i] != '\0'; i++) { if (isdigit(postfix[i])) { push(&s, postfix[i] - '0'); } else if (is_operator(postfix[i])) { b = pop(&s); a = pop(&s); switch (postfix[i]) { case '+': push(&s, a + b); break; case '-': push(&s, a - b); break; case '*': push(&s, a * b); break; case '/': if (b == 0) { printf("Division by zero!\n"); exit(1); } push(&s, a / b); break; case '^': push(&s, pow(a, b)); break; } } else { printf("Invalid character in expression!\n"); exit(1); } } return pop(&s); } int main() { char infix[MAX_SIZE], postfix[MAX_SIZE]; printf("Enter an infix expression: "); scanf("%s", infix); infix_to_postfix(infix, postfix); printf("Postfix expression: %s\n", postfix); printf("Result: %g\n", evaluate_postfix(postfix)); return 0; } ``` 注意,在计算后缀表达式时,数字字符需要换为数字,可以使用字符减去字符'0'的方式实现。此外,需要注意除数为零和括号匹配的情况。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值