C语言实现加减乘除的括号计算器

文章介绍了如何使用C语言实现后缀表达式的求值,利用栈来处理运算符和数字,根据运算符优先级进行计算,最终得到结果。
摘要由CSDN通过智能技术生成

#include<stdbool.h>
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<strings.h>
#include<stdlib.h>
#ifndef stack_h 
#define stack_h
#include <stddef.h> // for size_t

typedef char ele;//栈的类型 

// 定义栈结构体,包含栈顶指针、容量和当前元素数量等信息
typedef struct {
    ele* data;     // 栈内存储数据的数组
    size_t capacity; // 栈的总容量
    size_t count;   // 当前栈内元素数量
}zhan;
// 初始化栈,分配指定容量的内存空间
zhan space(size_t capacity) {
    zhan stack = {0};
    stack.capacity = capacity;
    stack.data = malloc(capacity * sizeof(*stack.data));
    return stack;
}
// 压一个元素进栈
void in(zhan* stack, ele element) {
    stack->data[stack->count++] = element;
}
// 判断栈是否为空
int iskong(const zhan* stack) {
    return stack->count == 0;
}
// 从栈中弹出一个元素
ele out(zhan* stack) {
    // 保存即将弹出的栈顶元素的值
    char top_element = stack->data[stack->count - 1];
    // 弹出操作:减少计数并将栈顶元素置为 '\0'
    stack->data[--stack->count] = '\0';
    // 返回栈顶元素的原值
    return top_element;
}
// 获取栈顶元素(但不弹出)
ele gettop(const zhan* stack) {
    return stack->data[stack->count - 1];
}
#endif // stack_h
char s[100];
int cmp(char a, char b){
    // 定义运算符优先级映射表
    const int priority[] = {
        ['+'] = 1,
        ['-'] = 1,
        ['*'] = 2,
        ['/'] = 2,
    };
    // 比较优先级值
    if(priority[a] >= priority[b]){
        return 1;
    }
    else{
        return 0;
    }
}
double cal(double a, double b, char c) {
    switch (c) {
        case '+':
            return a + b;
        case '-':
            return a - b;
        case '*':
            return a * b;
        case '/':
            return a / b;
    }
}
int main(){
    while(1){//循环 
    char tmpa;
    int n=0;

    while(scanf("%c",&tmpa)){
        if(tmpa=='='){
            s[n]='=';
            goto next;
        }
        if(tmpa!=' '){
            s[n]=tmpa;
            n++;
        }
    }
    next:;
    s[n+1]='\0';
    int a[100];//储存数字 
    char b[100];//储存运算符 
    int num_count = 0;
    int op_count = 0;

    for (int i = 0; s[i] != '\0'; ++i) {
        if (isdigit(s[i])) { // 遇到数字
            int j = i;
            while (isdigit(s[j]) && j < sizeof(s) - 1) { // 扩展到整个数字
                ++j;
            }
            char num_str[j - i + 1];
            strncpy(num_str, &s[i], j - i);
            num_str[j - i] = '\0';
            a[num_count++] = atoi(num_str); // 将数字字符串转换为整数并存入数组
            i = j - 1; // 跳过已处理的数字字符
        } else{ // 遇到运算符
            a[num_count++] = -1; // 在a数组中用-1标记运算符位置
            b[op_count++] = s[i]; // 存储运算符到数组
        }
    }
    a[num_count]=-2;
    //现在已经完成输入,开始改变为后缀运算式
    zhan op=space(100);//操作栈 
    int abac[100];
    char bbac[100];
    int bbac1=0,abac1=0;
    char rubbish;//你不会再用到我的 
    int j=0,bcnt=0;
    while(a[j]!=-2){
        if(a[j]!=-1){
            abac[abac1++]=a[j];//数字进入 
            j++;
        }
        else{
            if(b[bcnt]!=')'){//不是右括号,判断优先级,栈内如果大出栈,直到小或空,栈内小则入栈 
                if(iskong(&op)!=0){//空栈,直接进入 
                    in(&op,b[bcnt++]);//录入当前操作到栈 ,注意这里不用标记 
                    j++;
                    goto again;
                }else{
                    if(b[bcnt]=='('){//左括号,直接进入 
                        in(&op,b[bcnt++]);//录入当前操作到栈 ,注意这里不用标记 
                        j++;
                        goto again;
                    }        
                     else{
                         top:
                        if(cmp(gettop(&op),b[bcnt])>0&&iskong(&op)==0){//栈内优先,出栈(不为空)
                            bbac[bbac1++]=out(&op);//弹出到字符串 
                            abac[abac1++]=-1;//标记运算符 
                            if(iskong(&op)>0||cmp(gettop(&op),b[bcnt])==0){
                                goto fuck;//空栈或优先级高,录入 
                            }
                            goto top;//循环 
                        }
                        fuck:;
                        in(&op,b[bcnt++]);//录入当前操作到栈 ,注意这里不用标记 
                        j++;
                        goto again;
                    }
                        
                }
            }
            else{//右括号,弹出,直到左括号 
                bcnt++; 
                while(gettop(&op)!='('){
                    bbac[bbac1++]=out(&op);//弹出到字符串 
                    abac[abac1++]=-1;//标记运算符 
                }
                rubbish=out(&op);//销毁栈中括号 
                j++;
                goto again;
            }
        }
        again:;
    }
    while(iskong(&op)==0){//栈没清干净
        if(gettop(&op)!='('&&gettop(&op)!='='){
            bbac[bbac1++]=out(&op);//弹出到字符串 
            abac[abac1++]=-1;//标记运算符
        }
        else{
            rubbish=out(&op);
        }
    }//这之后所有的后缀数据记录在了abac和bbac中

    abac[abac1]=-2;//总得有个结尾吧 
    double tmp1,tmp2;
    double num[1000];
    int i=0,num1=0;
    bbac1=0;
    while(abac[i]!=-2){
        if(abac[i]!=-1){
            num[num1]=(double)abac[i];//入栈 
            num1++;
            i++;
        }
        else{
            tmp2=num[num1-1];
            num1--;
            tmp1=num[num1-1];
            num1--;//最上面两个出栈 
            num[num1]=cal(tmp1,tmp2,bbac[bbac1]);//计算,结果储存到栈中 
            i++;
            bbac1++;
            num1++;
        }
    }
    printf("%.2lf\n\n",num[0]);//最后栈中只剩下一个结果数据 
            }//循环 
    return 0;
}

//主要使用后缀表达式原理
 

  • 16
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
为了应付作业而编的,一个新手,请大家多多指教。/** * Title: Calculator * Description: * Copyright: Copyright (c) 2004 * Company: CUIT * Calculator.java * Created on 2004年10月13日, 下午2:35 * @author jacktom * @version 1.0*/import java.awt.*;import java.awt.event.*;import javax.swing.*;public class Calculator extends JFrame implements ActionListener{ Operator oper; String a,result; int type; boolean flag1=false; boolean flag2=false; boolean judge=true; int count=0; JTextField text; JPanel jpanel[]; JPanel jpanel1; JButton jbutton[]; String name[]={"0",".","-/+","+","=","1","2","3","-",")","4","5","6","*","(","7","8","9","/","CE"}; //Construct the JFrame public Calculator() { oper=new Operator(); setSize(250,300); setVisible(true); //Overridden so we can exit when window is closed this.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { dispose(); System.exit(0); } }); Container con=getContentPane(); con.setLayout(new GridLayout(5,5)); text=new JTextField(12); text.setHorizontalAlignment(JTextField.RIGHT); jpanel1=new JPanel(); jpanel1.setLayout(new GridLayout(1,1)); jpanel1.add(text); jpanel=new JPanel[4]; for(int i=0;i<4;i++) { jpanel[i]=new JPanel(); jpanel[i].setLayout(new GridLayout(1,5)); } jbutton=new JButton[name.length]; //add button to panel for(int j=0;j=0;i--) { con.add(jpanel[i]); } } public void actionPerformed(ActionEvent e) { for(int i=0;i<10;i++) { if(e.getActionCommand().equals(String.valueOf(i))) if(flag1==false) { text.setText(String.valueOf(i)); flag1=true; } else { text.setText(text.getText()+i); } } if(e.getActionCommand().equals(".")) if(flag2==false&&count==0) { text.setText(text.getText()+"."); count++; flag1=true; } if(e.getActionCommand().equals("+")||e.getActionCommand().equals("-")||e.getActionCommand().equals("*")||e.getActionCommand().equals("/")) { if(judge) { a=text.getText(); oper.EvaluateExpression(a); } else judge=true; flag1=false; flag2=false; count=0; if(e.getActionCommand().equals("+")) { a="+"; oper.EvaluateExpression(a); } if(e.getActionCommand().equals("-")) { a="-"; oper.EvaluateExpression(a); } if(e.getActionCommand().equals("*")) { a="*"; oper.EvaluateExpression(a); } if(e.getActionCommand().equals("/")) { a="/"; oper.EvaluateExpression(a); } } if(e.getActionCommand().equals("=")) { if(judge) { a=text.getText(); oper.EvaluateExpression(a); } else judge=true; oper.EvaluateExpression("#"); text.setText(""); text.setText(String.valueOf(oper.CalculateResult())); flag1=false; flag2=false; count=0; } if(e.getSource()==jbutton[2]) { text.setText("-"+text.getText()); } if(e.getActionCommand().equals(")")) { a=text.getText(); oper.EvaluateExpression(a); oper.EvaluateExpression(")"); judge=false; } if(e.getActionCommand().equals("CE")) { text.setText(""); judge=true; count=0; flag1=false; flag2=false; oper=new Operator(); } if(e.getActionCommand().equals("(")) { oper.EvaluateExpression("("); } } /** * Main method * * @param args String[] */ public static void main(String args[]) { Calculator Cmain=new Calculator(); Cmain.pack(); }}/** * Operator.java * Description:用栈实现计算 * Created on 2004年10月13日, 下午3:35 * @author jacktom*/public class Operator{ StackY optr; //存放操作符 StackY opnd;//存放操作数 Puzhu p; boolean Mark; Operator() { p=new Puzhu(); optr=new StackY(); opnd=new StackY(); optr.push("#"); } public void EvaluateExpression(String s) { boolean mark=true; if(s=="+"||s=="-"||s=="*"||s=="/"||s=="("||s==")"||s=="#") { while(mark) { switch(p.Precede(optr.peek(),s)) { case -1: optr.push(s); mark=false; break; case 0: optr.pop(); mark=false; break; case 1: String theta=optr.pop(); String a =opnd.pop(); String b =opnd.pop(); if(a.indexOf(".",0)==-1&&b.indexOf(".",0)==-1) Mark=true; else Mark=false; double c=Double.valueOf(a).doubleValue(); double d=Double.valueOf(b).doubleValue(); double e=p.Operate(c,theta,d); String f=String.valueOf(e); if(theta=="/") Mark=false; if(Mark) opnd.push(f.substring(0,f.indexOf(".",0))); else opnd.push(f); break; } } } else opnd.push(s); } public String CalculateResult() { //double result=Double.valueOf(opnd.peek()).doubleValue(); return opnd.peek(); }}/** * Description:判断操作符的优先级并计算结果 * Created on 2004年10月13日, 下午4:00 * @author jacktom*/class Puzhu{ public Puzhu() {} public int Precede(String optr1,String optr2) { String[] A={"+","-","*","/","(",")","#"}; int[][] B={ {1,1,-1,-1,-1,1,1}, {1,1,-1,-1,-1,1,1}, {1,1,1,1,-1,1,1}, {1,1,1,1,-1,1,1}, {-1,-1,-1,-1,-1,0,2}, {1,1,1,1,2,1,1}, {-1,-1,-1,-1,-1,2,0}, }; int i=0,j=0,k; while(i<7) { if(A[i]==optr1) { break; } i++; } while(j<7) { if(A[j]==optr2) { break; } j++; } k=B[i][j]; return k; } public double Operate(double a,String oper,double b) { double c=0; if(oper=="+") c=a+b; if(oper=="-") c=b-a; if(oper=="*") c=a*b; if(oper=="/") c=b/a; return c; }}/** * StackY.java * Description:堆栈的基本操作实现 * Created on 2004年10月13日, 下午3:05 * @author jacktom*/public class StackY { private int maxSize; // size of stack array private String[] stackArray; private int top; // top of stack public StackY(int s) // constructor { maxSize = s; // set array size stackArray = new String[maxSize]; // create array top = -1; // no items yet }public StackY() // constructor { maxSize = 20; // set array size stackArray = new String[maxSize]; // create array top = -1; // no items yet } public void push(String j) // put item on top of stack { top++; stackArray[top] = j; // increment top, insert item } public String pop() // take item from top of stack { return stackArray[top--]; // access item, decrement top } public String peek() // peek at top of stack { return stackArray[top]; } public boolean isEmpty() // true if stack is empty { return (top == 0); } }

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值