C语言使用动态栈实现四则运算算数表达式求解识别(+-*/())使用中缀表达式转后缀表达式

识别运算表达式,当识别到=号后计算结果,如果识别不到=输入,则报错。同时,对错误输入进行处理,包含处理:输入括号数量错误、输入非数字错误、非运算符错误。

通过使用动态栈,主要练习C语言栈相关操作。

1 栈操作头文件

/***********************************************************
    @File name: stack.h
    @Author: xueya   /DreCoder
    @Date: 2022/8/5 17:04
    @Version:1.0
    @Description: 栈相关操作头文件
    @other:
    @Copyright (c) 2022 , All rights reserved.
***********************************************************/
#ifndef XUEYA_CTEST_STACK_H
#define XUEYA_CTEST_STACK_H

#include <malloc.h>

typedef enum BOOL{
    false,true
}bool;

typedef struct Node{
    char data;
    struct Node * pNext;
}NODE,*pNODE;

typedef struct NodeInt{
    int data;
    struct NodeInt * pNext;
}NODEINT,*pNODEINT;

typedef struct Stack{
    pNODE pTop;
    pNODE pBottom;
}STACK,*pSTACK;

typedef struct StackInt{
    pNODEINT pTop;
    pNODEINT pBottom;
}STACKINT,*pSTACKINT;

void  initStack(pSTACK pS);
void  initStackInt(pSTACKINT pS);

void  pushStackInt(pSTACKINT pS,int value);
void  pushStack(pSTACK pS,char value);
char stack_pop(pSTACK p_stack);
int stack_popInt(pSTACKINT p_stack);
bool stack_is_empty(pSTACK p_stack);
bool stack_is_emptyInt(pSTACKINT p_stack);

#endif //XUEYA_CTEST_STACK_H

2 栈操作相关函数实现

使用两个栈,一个栈为保存数据的栈,一个栈为保存运算符的栈.

/***********************************************************
    @File name: stack.c
    @Author: xueya   /DreCoder
    @Date: 2022/8/5 17:04
    @Version:1.0
    @Description: 栈操作相关函数操作
    @other:
    @Copyright (c) 2022 , All rights reserved.
***********************************************************/
#include "stack.h"
#include <stdio.h>


void  initStack(pSTACK pS)
{
    pS->pTop=(pNODE) malloc(sizeof (NODE));
    if( pS->pTop==NULL ){
        printf("memory malloc failed\n");
        return;
    }else {
        pS->pBottom=pS->pTop;
        pS->pBottom->pNext=NULL;
    }

}
void  initStackInt(pSTACKINT pS)
{
    pS->pTop=(pNODEINT) malloc(sizeof (NODEINT));
    if( pS->pTop==NULL ){
        printf("memory malloc failed\n");
        return;
    }else {
        pS->pBottom=pS->pTop;
        pS->pBottom->pNext=NULL;
    }

}
void  pushStack(pSTACK pS,char value)
{
    pNODE pNew=(pNODE) malloc(sizeof (NODE));
    pNew->data=value;
    pNew->pNext=pS->pTop;
    pS->pTop=pNew;
}
void  pushStackInt(pSTACKINT pS,int value)
{
    pNODEINT pNew=(pNODEINT) malloc(sizeof (NODEINT));
    pNew->data=value;
    pNew->pNext=pS->pTop;
    pS->pTop=pNew;
}

//把p_stack所指向的栈出栈一次
//返回出栈成功还是失败
//
char stack_pop(pSTACK p_stack)
{
    char ret;
    if (stack_is_empty(p_stack))
    {
       return ret=16;
    }
        pNODE temp=p_stack->pTop;//保存栈顶指针,用于释放
        ret=p_stack->pTop->data;
        p_stack->pTop=temp->pNext;
        free(temp);
        temp=NULL;
        return ret;
}


int stack_popInt(pSTACKINT p_stack)
{
        pNODEINT temp=p_stack->pTop;//保存栈顶指针,用于释放
        int val=p_stack->pTop->data;
        p_stack->pTop=temp->pNext;
        free(temp);
        temp=NULL;
    return val;
}


bool stack_is_empty(pSTACK p_stack)
{
    if( p_stack->pTop==p_stack->pBottom ) {
        return true;
    }else {
        return false;
    }
}

bool stack_is_emptyInt(pSTACKINT p_stack)
{
    if( p_stack->pTop==p_stack->pBottom ) {
        return true;
    }else {
        return false;
    }
}

3 计算相关操作实现

/***********************************************************
    @File name: xueya_Ctest05.c
    @Author: xueya   /DreCoder
    @Date: 2022/8/1 11:57
    @Version:1.0
    @Description: 计算器程序,能接收用户输入的四则运算计算式,
                直到用户输入等号=,把结果打印出来
                要求:对输入做验证,非法的输入需要提示,支持的运算符包含+-*\/(/)
    @other:
    @Copyright (c) 2022 , All rights reserved.
***********************************************************/
#include <stdio.h>
#include "stack.h"
#include <string.h>
#include <stdlib.h>


void str_append_char(char * str,char ch);
char * str_to_postfix(char * str);
int calValue(char * str);
bool JudgeDataByUser(char * str);


int main()
{
    char user_str[100];//转换后的输入字符串
    char user_strAfter[100];
    memset(user_strAfter,0,100);
    char * postfix=(char *) malloc(sizeof (char)*200);
    int length=0,result=0;
    system("clear");
    printf("\n");
    printf("============================================================\n");
    printf("|       Please enter a numeric expression after >>          |\n");
    printf("|       Enter the equal sign and  press enter to            |\n");
    printf("|                           calculate the result.           |\n");
    printf("|       This calculation program only supports              |\n");
    printf("|                           integer calculation.            |\n"); 
    printf("|       eg.12*(5+9-10/2)-5=                                 |\n");
    printf("=============================================================\n");
    printf("\n");
    printf("Please enter a numeric expression:\n");
    printf(">>");
    scanf("%s",user_str);
    if( !JudgeDataByUser(user_str )){
        printf("Input error, please try again!\n");
        return -1;
    }
    length=strlen(user_str);

    strncpy(user_strAfter,user_str, length-1);
    str_append_char(user_strAfter,'\0');
    //printf("Afterlen=%d\n", strlen(user_strAfter));
    postfix=str_to_postfix(user_strAfter);
    result=calValue(postfix);
    printf("=============================================================\n");
    printf("\n");
    printf(">> %s%d\n\n",user_str,result);
    printf("End of calculation, thank you for using!       \n");
    printf("=============================================================\n");
    return 0;
}

void str_append_char(char * str,char ch)
{
   // printf("append_char=%s\n",str);
    while (*str) str++;
    *str++=ch;
    *str='\0';
}

bool JudgeDataByUser(char * str)
{
    int length=strlen(str),char_sum=0,brackets=0;
    if( *(str+length-1)!='=' ){
        return false;
    }
    while (*str) {
        if ((*str >='(' && *str <='+' )||(*str>='/' && *str<='9')||(*str=='-')||(*str=='=')){
            if( *str =='(')
                brackets=1;
            if( *str ==')')
                brackets=2;
            char_sum++;
            if (length == char_sum) {
                if (brackets == 0) {
                    return true;
                } else {
                    if (brackets == 2) {
                        return true;
                    }
                }
            }
        }
        str++;
    }
    return false;
}

char * str_to_postfix(char * str)
{
    STACK S;
    initStack(&S);//初始化栈

    char postfix[200]={0};
    char * ret_str=(char *) malloc(sizeof (char)*200);

    int i=0;
    int length= strlen(str);
    char pop_char;

    while (i<length)
    {
        char ch =str[i];
        switch (ch) {
            case '+':
            case '-':
            {
                while ((stack_is_empty(&S)==false)&&((S.pTop->data!='(')))
                    str_append_char(postfix, stack_pop(&S));
                pushStack(&S,ch);
                i++;
                break;
            }
            case '*':
            case '/':
            {
                while ((stack_is_empty==false)&&((S.pTop->data=='*')||(S.pTop->data=='/')))
                    str_append_char(postfix, stack_pop(&S));
                pushStack(&S,ch);
                i++;
                break;
            }
            case '(':
            {
                pushStack(&S,ch);
                i++;
                break;
            }

            case ')': //遇到右括号进行出栈,若为空,返回null
            {
                pop_char=stack_pop(&S);
                while ((pop_char!=16) && (pop_char!='('))
                {
                    str_append_char(postfix,pop_char);
                    pop_char=stack_pop(&S);
                }
                i++;
                break;
            }
            default:
            {
                while (i<length&&(ch>='0'&&ch<='9'))//处理数字
                {
                    str_append_char(postfix,(char)ch);
                    i++;
                    if( i<length ){
                        ch=str[i];
                    }
                }
                str_append_char(postfix,' ');
            }

        }
    }
    while (stack_is_empty(&S)==false)
        str_append_char(postfix,stack_pop(&S));
    //str_append_char(postfix,'\0');
    strcpy(ret_str,postfix);


    return ret_str;
}

int calValue(char * str)
{
    STACKINT S;
    initStackInt(&S);//初始化栈
    //printf("strlen=%d\n", strlen(str));
    int value=0,length= strlen(str);
    char nums[10];
    for (int i = 0; i <length ; i++) {
        int index=0;
        char ch=str[i];
        if( ch>='0' && ch <='9'){
            while (ch!=' ')
            {
                nums[index]=ch;
                index++;
                i++;
                ch=str[i];
            }
            nums[index]='\0';
            int re= atoi(nums);
            pushStackInt(&S, re);
        }else if( ch!=' ' ){
            int num2=stack_popInt(&S);
            int num1=stack_popInt(&S);
            switch (ch) {
                case '+':
                    value=num1+num2;
                    break;
                case '-':
                    value=num1-num2;
                    break;
                case '*':
                    value=num1*num2;
                    break;
                case '/':
                    if(!num2){
                        value=0;
                        printf("除数不能为0\n");
                        break;
                    }else{
                        value=num1/num2;
                    }
                    break;
            }
            pushStackInt(&S,value);
        }
    }
    return stack_popInt(&S);
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一个简单的Java代码,使用GUI界面输出实现算术表达式到抽象语法树的转换: ```java import java.awt.BorderLayout; import java.awt.EventQueue; import java.awt.Font; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Stack; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.SwingConstants; import javax.swing.border.EmptyBorder; public class ExpressionTreeGUI extends JFrame { private JPanel contentPane; private JTextField textField; private JLabel resultLabel; public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { ExpressionTreeGUI frame = new ExpressionTreeGUI(); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } public ExpressionTreeGUI() { setTitle("Expression Tree Converter"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setBounds(100, 100, 450, 300); contentPane = new JPanel(); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); setContentPane(contentPane); JPanel inputPanel = new JPanel(); contentPane.add(inputPanel, BorderLayout.NORTH); JLabel inputLabel = new JLabel("Input Infix Expression:"); inputPanel.add(inputLabel); textField = new JTextField(); inputPanel.add(textField); textField.setColumns(20); JButton convertButton = new JButton("Convert"); convertButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String infix = textField.getText(); String postfix = infixToPostfix(infix); TreeNode root = postfixToTree(postfix); resultLabel.setText("Result: " + root.toString()); } }); inputPanel.add(convertButton); JPanel outputPanel = new JPanel(); contentPane.add(outputPanel, BorderLayout.CENTER); outputPanel.setLayout(new GridLayout(0, 1, 0, 0)); resultLabel = new JLabel("Result:"); resultLabel.setFont(new Font("Lucida Grande", Font.BOLD, 16)); resultLabel.setHorizontalAlignment(SwingConstants.CENTER); outputPanel.add(resultLabel); } private int precedence(char operator) { if (operator == '+' || operator == '-') { return 1; } else if (operator == '*' || operator == '/') { return 2; } else { return 0; } } private String infixToPostfix(String infix) { StringBuilder postfix = new StringBuilder(); Stack<Character> stack = new Stack<>(); for (int i = 0; i < infix.length(); i++) { char ch = infix.charAt(i); if (ch == ' ') { continue; } if (Character.isDigit(ch)) { postfix.append(ch); } else if (ch == '+' || ch == '-' || ch == '*' || ch == '/') { while (!stack.empty() && precedence(ch) <= precedence(stack.peek())) { postfix.append(stack.pop()); } stack.push(ch); } else if (ch == '(') { stack.push(ch); } else if (ch == ')') { while (!stack.empty() && stack.peek() != '(') { postfix.append(stack.pop()); } stack.pop(); } } while (!stack.empty()) { postfix.append(stack.pop()); } return postfix.toString(); } private TreeNode postfixToTree(String postfix) { Stack<TreeNode> stack = new Stack<>(); for (int i = 0; i < postfix.length(); i++) { char ch = postfix.charAt(i); if (Character.isDigit(ch)) { TreeNode node = new TreeNode(ch - '0'); stack.push(node); } else { TreeNode right = stack.pop(); TreeNode left = stack.pop(); TreeNode node = new TreeNode(ch, left, right); stack.push(node); } } return stack.pop(); } private class TreeNode { char operator; int operand; TreeNode left; TreeNode right; public TreeNode(char operator, TreeNode left, TreeNode right) { this.operator = operator; this.left = left; this.right = right; } public TreeNode(int operand) { this.operand = operand; } @Override public String toString() { if (operand != 0) { return Integer.toString(operand); } else { String leftStr = left.toString(); String rightStr = right.toString(); return "(" + leftStr + " " + operator + " " + rightStr + ")"; } } } } ``` 这个程序使用了Swing库来创建GUI界面。用户可以输入一个中缀表达式,然后单击“Convert”按钮,程序将把该表达式转换为后缀表达式,然后构建一个抽象语法树,并将其显示在GUI中。程序使用了一个实现转换和构建树的过程。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值