✅简介:与大家一起加油,希望文章能够帮助各位!!!!
💬保持学习、保持热爱、认真分享、一起进步!!!
实验任务:
实现一个简单的计算器,输入一个算术表达式,其运算符包含圆括号、加、减、乘、除、求余等符号,输出该算术表达式的值。要求:
(1)系统至少能实现加、减、乘、除、求余等运算;
(2)利用栈的后进先出特性实现;
首先实验要求的前提是我们能够深度的理解栈的特性,利用这个特性去设计程序。
在计算器的实现中,可以利用栈的特性来处理运算符和操作数。以下是一个简单的实现思路:
创建两个栈,一个操作数栈(operand stack),用于存储数字,另一个运算符栈(operator stack),用于存储运算符。
从左到右逐个读取表达式的字符。
如果遇到数字,将其压入操作数栈。
如果遇到左括号,将其压入运算符栈。
如果遇到运算符(加、减、乘、除、求余等),将其与运算符栈的栈顶元素进行比较:
- 若运算符栈为空或栈顶元素为左括号,直接将当前运算符压入运算符栈。
- 若当前运算符优先级高于栈顶元素,将当前运算符压入运算符栈。
- 否则,将栈顶运算符弹出,并从操作数栈中弹出两个操作数进行运算,将得到的结果压入操作数栈。重复此步骤,直至当前运算符优先级较高或运算符栈为空,再将当前运算符压入运算符栈。
如果遇到右括号,不断弹出运算符栈的栈顶元素,并从操作数栈中弹出相应数量的操作数进行运算,将结果压入操作数栈,直至遇到左括号为止。
重复步骤2至6,直至表达式遍历完毕。
最后,操作数栈中唯一剩下数字即为算术表达式的值。
具体实现代码如下:
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#define OK 1
#define False 0
#define max 200
typedef struct{
int Stack_n[max];//数栈
char Stack_o[max];//操作符栈
int N,O;
}SqStack;
int init_sq(SqStack* Sq);
int Priority(char op);
int Calculate(int num1,int num2,char op);
int main(){
SqStack Sq;
init_sq(&Sq);
printf("请输入要计算的表达式:\n");
char s[100];
//scanf("%s",s);
fgets(s, sizeof(s), stdin);
int len=strlen(s);
if(s[len-1]=='\n') s[--len]='\0';
len=strlen(s);
//-------------------------------------------
//定义一个临时变量
int temp,num;
for(int i=0;i<len;i++){
if(s[i]==' ') continue;
if(s[i]=='('){
Sq.Stack_o[Sq.O++]=s[i];
}
if(s[i]==')'){
if(Sq.Stack_o[Sq.O-1]=='(')
Sq.O--;
else{
while (Sq.Stack_o[Sq.O-1] != '(') {
int num1 = Sq.Stack_n[--Sq.N];
int num2 = Sq.Stack_n[--Sq.N];
num = Calculate(num2,num1,Sq.Stack_o[--Sq.O]);
Sq.Stack_n[Sq.N++] = num;
}
//弹出左括号
Sq.O--;
}
}
if(isdigit(s[i])){
//temp清零
temp=0;
while(isdigit(s[i])) {
temp=temp*10+s[i++]-'0';
}
//当isdigit返回值为0时,那时候的字符没有被读取,退回一位
i--;
Sq.Stack_n[Sq.N++]=temp;//入栈
}
else{
//如果是运算符,执行以下逻辑
if(Priority(s[i])==4) continue;
while(Sq.O!=0&&Priority(Sq.Stack_o[Sq.O-1])>=Priority(s[i])&&Sq.N>=2&&Priority(Sq.Stack_o[Sq.O-1])!=4){
int num1 = Sq.Stack_n[--Sq.N];
int num2 = Sq.Stack_n[--Sq.N];
num=Calculate(num2,num1,Sq.Stack_o[--Sq.O]);
Sq.Stack_n[Sq.N++]=num;
}
Sq.Stack_o[Sq.O++]=s[i];//入栈
}
}
// 遍历完表达式后,依次将剩余的操作符进行计算
while (Sq.O != 0) {
int num1 = Sq.Stack_n[--Sq.N];
int num2 = Sq.Stack_n[--Sq.N];
num = Calculate(num2,num1,Sq.Stack_o[--Sq.O]);
Sq.Stack_n[Sq.N++] = num;
}
printf("%d",Sq.Stack_n[--Sq.N]);
return 0;
}
int init_sq(SqStack* Sq){
if(Sq==NULL)
return False;
Sq->N=Sq->O=0;
return OK;
}
int Priority(char op){
switch (op) {
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
case '%' :
return 3;
case '(' :
case ')' :
return 4;
default:
return -1;
}
}
int Calculate(int num1,int num2,char op){
if(op=='+') return num1+num2;
if(op=='-') return num1-num2;
if(op=='*') return num1*num2;
if(op=='/') return num1/num2;
if(op=='%') return num1%num2;
}
总结:
在操作的过程中,需要我们注意一下几点:
- 算术表达式的解析。
- 运算符的优先级的处理(重点)。
- 基本运算逻辑。
以上均是个人的理解,如果有不对的地方请各位大佬帮忙斧正!!
追光的人,终会光芒万丈!!