Kssadin 2024-06-26 00:23 采纳率: 0%
浏览 2

后缀表达式算法计算问题


#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include <stdbool.h>
#define ERROR 0
#define MAX 100
#include<iostream>
#include <string.h>
typedef struct                                          //用两个栈来别分存储运算数和运算符double char
{
    int top;
    double items[MAX];
} DoubleStack;

typedef struct {
    int top;
    char items[MAX];
} CharStack;

void pushDouble(DoubleStack *s, double item) {
    if (s->top < MAX) {
        s->top = s->top + 1;
        s->items[s->top] = item;
    } else {
        printf("栈已满。\n");
    }
}

double popDouble(DoubleStack *s) {
    if (s->top > 0) {
        return s->items[s->top--];
    } else {
        printf("栈为空。\n");
        return ERROR;
    }
}


void pushChar(CharStack *s, char item)             //入栈
 {
    if (s->top < MAX - 1) {
        s->top = s->top + 1;
         s->items[s->top] = item;

    } else {
        printf("栈已满。\n");
    }
}

char popChar(CharStack *s)                        //出栈
{
    if (s->top >= 0) {
        return s->items[s->top--];
    } else {
        printf("栈为空。\n");
        return '\0';
    }
}
char getTop(CharStack *stack) {
    if (stack->top >= 0) {
        return stack->items[stack->top];
    }
    return '\0'; // 返回空字符表示栈为空
}

int isoperator(char symbol)        //判断char栈中字符是否为运算符
{
    if (symbol == '+' || symbol == '-' || symbol == '*' || symbol == '/')
    {
        return 1; // 返回1表示是运算符
    }
    else
    {
        return 0; // 返回0表示不是运算符
    }
}

int precedence(char symbol)  //判断运算符的优先级  switch case函数
{
    switch (symbol) {
        case '+':
        case '-':
            return 1;
        case '*':
        case '/':
            return 2;
        default:
            return 0;
    }
}

double operate(double a, double b, char op)  //给出各运算符的运算操作
{
    switch (op) {
        case '+': return a + b;
        case '-': return a - b;
        case '*': return a * b;
        case '/':
            if (b != 0) {
                return a / b;
            } else {
                printf("错误:除数不能为零。\n");
                return ERROR;
    }
}
}

int expression(char *expression) {
    int length = strlen(expression);
    int count_bracket = 0;
    int last_was_digit = 0;
    int has_operator = 0;
    int count_operator = 0;

    for (int i = 0; i < length; i++) {
        char ch = expression[i];

        if (isdigit(ch)) {
            last_was_digit = 1;
            has_operator = 0;
            count_operator--;
        } else if (isoperator(ch)) {
            has_operator = 1;
            count_operator++;
            last_was_digit = 0;
        } else if (ch == '(') {
            count_bracket++;
        } else if (ch == ')') {
            count_bracket--;
            if (count_bracket < 0) {
                printf("括号不匹配:右括号多于左括号\n");
                return 0;
            }
        } else {
            printf("非法字符:%c\n", ch);
            return 0;
        }


    }

    if (count_bracket != 0) {
        printf("括号不匹配:左括号多于右括号\n");
        return 0;
    } else if (!last_was_digit || count_operator > 0) {
        printf("算术表达式不合法\n");
        return 0;
    } else {
        printf("括号匹配正确,算术表达式合法\n");
        return 1;
    }
}




void infixToPostfix(const char *infix, char *postfix) {
    CharStack stack; //字符栈
    stack.top=-1;    //将其置空
    int i = 0, j = 0;  //i j分别用来遍历infix和postfix
    char c;

    while (infix[i] != '\0') //只要infxi[i]不为空
        {
        c = infix[i];
        if (isdigit(c))  //如果c为数字
        {
            postfix[j++] = c; // 直接输出数字到postfix
        }
        else if (isoperator(c)) //如果c为运算符
            {
            while (precedence(getTop(&stack)) >= precedence(c)) //判断此运算符的优先级   如果优先级小则把栈顶运算符弹出 进入postfix
            {
                postfix[j++] = popChar(&stack);
            }
            pushChar(&stack, c); //如果优先级大则入栈
        }
        else if (c == '(') {     //括号的入栈:遇见左括号直接入字符栈
            pushChar(&stack, c);
        }
        else if (c == ')') //当遇到右括号时
        {
            while (getTop(&stack) != '(') //在遇见左括号之前一直弹出栈中字符
                   {
                postfix[j++] = popChar(&stack);
            }
            popChar(&stack); // 最后弹出左括号
        }
        i++; //i进行循环+1
    }

    while (stack.top >= 0) //将栈里剩余的字符弹出
        {
        postfix[j++] = popChar(&stack);
    }
    postfix[j] = '\0'; // 结尾添加空字符
}
void evaluatePostfix(char* postfix, DoubleStack* stack)
 {
    char ch;
    double a, b, value;
    int i = 0;


    while (postfix[i] != '\0') {
        ch = postfix[i++];
        if (isdigit(ch))
            {
            pushDouble(stack,ch-'0' );
        }
        else if (isoperator(ch))
            {
            b = popDouble(stack);
            a = popDouble(stack);
            value = operate(a, b, ch);
            pushDouble(stack, value);
            printf("计算: %.2f %c %.2f = %.2f\n", a, ch, b, value);
        }
    }

}
int main()
{
    char infix[MAX], postfix[MAX];
    DoubleStack stack;
    stack.top = -1;

    printf("请输入算术表达式: ");
    scanf("%s", infix);

    if (expression(infix)) {
        infixToPostfix(infix, postfix);
        printf("后缀表达式: %s\n", postfix);
        evaluatePostfix(postfix, &stack);

        if (stack.top == 0) {
            printf("表达式的结果是: %.2f\n", popDouble(&stack));
        } else {
            printf("表达式无效或者栈操作错误。\n");
        }
    } else {
        printf("输入的表达式无效。\n");
    }

    return 0;
}

img


出现如图的问题 第一个操作数为0

  • 写回答

2条回答 默认 最新

  • 阿里嘎多学长 2024-06-26 00:23
    关注

    以下内容由CHATGPT及阿里嘎多学长共同生成、有用望采纳:


    根据你提供的代码和问题描述,我注意到了几个可能的问题点,这些问题可能导致了你在执行后缀表达式计算时遇到的问题。

    1. 输入处理:在main函数中,你使用了scanf("%s", infix);来读取表达式。这种方式可能会因为空格或特殊字符导致读取不正确。确保输入的表达式格式正确,没有多余的空格。

    2. 后缀表达式生成infixToPostfix函数负责将中缀表达式转换为后缀表达式。确保这个转换过程是正确的,特别是对于包含括号的表达式。

    3. 后缀表达式计算evaluatePostfix函数负责计算后缀表达式。问题可能出在对字符ch的处理上。你的代码中,将字符ch直接转换为数字并压入栈中,这在处理单个数字时是正确的,但如果数字有多位数,这种方法就会出错。另外,你的popDouble函数在栈为空时返回ERROR,这可能不是一个好的实践,因为它可能导致后续操作出现问题。

    4. 栈操作:在evaluatePostfix函数中,你需要确保在执行运算之前,栈中至少有两个操作数。如果栈中元素不足,就不应该执行运算。

    5. 错误处理:你的代码在遇到错误时打印错误信息,但并没有停止执行或返回错误代码。这可能导致程序在错误状态下继续执行,从而产生不正确的结果。

    6. 代码逻辑:在expression函数中,你使用了count_operator变量,但它在函数开始时没有初始化,这可能导致未定义的行为。

    7. 代码风格:代码中存在一些风格问题,比如变量命名不一致(例如has_operatorlast_was_digit),以及一些未使用的变量(例如count_bracket)。

    针对你的问题,我建议以下步骤:

    • 确保输入的表达式格式正确,没有多余的空格或特殊字符。
    • 仔细检查infixToPostfix函数,确保中缀表达式到后缀表达式的转换是正确的。
    • 修改evaluatePostfix函数,确保在执行运算之前栈中有足够的操作数,并且正确处理多位数的情况。
    • 在遇到错误时,适当地停止执行或返回错误。
    • 清理和统一代码风格,确保所有变量都有明确和一致的命名。

    如果你需要进一步的帮助,可以提供更具体的错误信息或代码段,我可以更详细地分析问题所在。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 6月26日

悬赏问题

  • ¥15 求高通平台Softsim调试经验
  • ¥15 canal如何实现将mysql多张表(月表)采集入库到目标表中(一张表)?
  • ¥15 wpf ScrollViewer实现冻结左侧宽度w范围内的视图
  • ¥15 栅极驱动低侧烧毁MOSFET
  • ¥30 写segy数据时出错3
  • ¥100 linux下qt运行QCefView demo报错
  • ¥50 F1C100S下的红外解码IR_RX驱动问题
  • ¥20 基于matlab的航迹融合 航迹关联 航迹插补
  • ¥15 用Matlab实现图中的光线追迹
  • ¥15 联想笔记本开机出现系统更新界面