Count.h
#ifndef AAA
#define AAA
#include<stdlib.h>
#include<assert.h>
#include<stdio.h>
#define NUMBER 20
typedef int DataType;
typedef struct Stack
{
char array[NUMBER];
int top;
}Stack;
typedef struct StackData
{
DataType array[NUMBER];
int top;
}StackData;
void StackInit(Stack *ret);
void Calculator(char *cur, StackData *ret);
void Infix(char *str, char (*cur)[NUMBER]);
#endif //AAA
Count.c
#include"Count.h"
//栈的初始化
void StackInit(StackData *ret)
{
assert(ret);
ret->top = 0;
}
//入栈
void StackPush(StackData *ret, DataType d)
{
assert(ret);
ret->array[ret->top] = d;
ret->top++;
}
//栈顶的数据
DataType StackTopCell(StackData *computer)
{
assert(computer);
if(computer->top == 0)
{
printf("栈空了\n");
return 0;
}
--computer->top;
return computer->array[computer->top];
}
//计算过程
//如果是数字的话直接入栈
//如果是操作符的话,取两次栈顶的元素,第一次取出的元素放在操作符的右边,第二次取出的元素放在操作符的左边,然后将计算的结果压入栈
//计算完成之后,取出栈顶的元素,此时栈顶的元素就是计算式的结果
void Calculator(char *cur, StackData *ret)
{
int i = 0;
while(cur[i])
{
if(cur[i] >= '0' && cur[i] <= '9')
{
char d = cur[i];
DataType c = atoi(&d);
StackPush(ret, c);
}
else
{
DataType b = StackTopCell(ret);
DataType a = StackTopCell(ret);
switch(cur[i])
{
case '+':
{
StackPush(ret, a+b);
};
break;
case '-':
{
StackPush(ret, a-b);
};
break;
case '*':
{
StackPush(ret, a*b);
};
break;
case '/':
{
if(cur == 0)
return;
StackPush(ret, a/b);
};
break;
}
}
i++;
}
}
//判断符号的先后顺序
DataType SymbolOrder(char cur)
{
DataType i = 0;
switch(cur)
{
case '+':
i = 1;
break;
case '-':
i = 1;
break;
case '*':
i = 2;
break;
case '/':
i = 2;
break;
case '(':
i = 3;
break;
case ')':
i = 4;
break;
default:
i = 0;
break;
}
return i;
}
中缀变后缀
//取栈顶的元素
DataType TopStack(Stack *cur)
{
return cur->array[cur->top-1];
}
//出栈
void PopStack(Stack *cur)
{
assert(cur);
cur->top--;
}
//入栈
void PushStack(Stack *ret, char d)
{
assert(ret);
ret->array[ret->top] = d;
ret->top++;
}
//判空
DataType EmptyStack(Stack cur)
{
if(cur.top == 0)
return 1;
return 0;
}
//中缀变后缀
//遇到字符数字的话,放入存放后缀表达式的数组中
//遇到左括号时,直接压入栈中
//遇到右括号时,开始出栈,直到栈顶元素为左括号时结束,且把左括号出栈
//遇到其他操作符时,查看栈此时是否为空,为空的话,直接入栈,不为空的话,与栈顶操作符比较,如果比栈顶操作符的优先级
//高的话,直接入栈,如果比栈顶的操作符低的话,栈顶元素开始出栈,出栈的元素放入存放后缀操作符的数组中,直到栈顶元素的优先级小于等于当前操作符时,停止出栈,
//将当前操作符入栈。如此反复,直到存放中缀表达式的数组内没有元素为止。然后将栈内剩余的操作符出栈,出栈的元素放入存放后缀表达式的数组内。
void Infix(char *str, char (*cur)[NUMBER])
{
Stack arr = {0};
DataType i = 0;
DataType j = 0;
while(str[i])
{
if(str[i] >= '0' && str[i] <= '9')
{
(*cur)[j] = str[i];
j++;
}
else if(str[i] == '(')
{
PushStack(&arr, str[i]);
}
else if(str[i] == ')')
{
while(TopStack(&arr) != '(')
{
(*cur)[j] = TopStack(&arr);
j++;
PopStack(&arr);
}
PopStack(&arr);
}
//当前符号的优先级大于栈顶元素的话,直接入栈
else if(SymbolOrder(str[i]) > SymbolOrder(arr.array[arr.top-1]) || EmptyStack(arr))
{
PushStack(&arr, str[i]);
}
//当前符号的优先级小于栈顶元素时,栈顶元素出栈,直到当前元素的优先级大于栈顶的优先级时停止
else if(SymbolOrder(str[i]) <= SymbolOrder(arr.array[arr.top-1]))
{
while(SymbolOrder(str[i]) <= SymbolOrder(arr.array[arr.top-1]) && !EmptyStack(arr) && arr.array[arr.top-1] != '(')
{
(*cur)[j] = arr.array[arr.top-1];
j++;
PopStack(&arr);
}
PushStack(&arr, str[i]);
}
i++;
}
//将栈中剩余的符号保存入数组
while(!EmptyStack(arr))
{
(*cur)[j] = TopStack(&arr);
j++;
PopStack(&arr);
}
}
主函数.c
#include"Count.h"
void Text()
{
char str[] = "0";
char cur[NUMBER] = "0";
printf("欢迎使用简单计算器,此计算器只可以使用0-9之间的简单运算\n");
printf("请输入你要计算的表达式:");
scanf("%s", str);
StackData ret = {0};
Infix(str, &cur);
Calculator(cur, &ret);
printf("计算后的结果是%d\n", ret.array[ret.top-1]);
}
int main()
{
Text();
return 0;
}