#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
typedef struct{
double* data;//int size;//容量
int top;//头指针位置
}Stack;
void initStack(Stack* p,int size){
p->size=size;
p->data=(double*)malloc(sizeof(double)*size);
p->top=-1;//数组初始无元素,索引为-1
}
int isEmpty(Stack* p){
return p->size==-1;//p->size=-1返回1,p->size!=-1返回0
}
int isFull(Stack* p){
return p->top==p->size-1;
}
void push(Stack* p,double value){//入栈
if(isFull(p)){
printf("满了\n");
exit(1);
}
p->top++;//p的索引++,要有对象
p->data[p->top]=value;
}
double pop(Stack* p){//出栈,返回出栈值
if(isEmpty(p)){
printf("删没了已经\n");
exit(1);
}
double value=p->data[p->top];
p->top--;//p的指针--,要有对象
return value;
}
double top(Stack* p){//获取栈顶元素,不出栈
if(isEmpty(p)){
printf("删没了已经\n");
exit(1);
}
return p->data[p->top];
}
//判断是不是运算符
int isOperator(char c) {
return c == '+' || c == '-' || c == '*' || c == '/';
}
// 获取运算符优先级
int getPriority(char op) {
switch (op) {
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
default:
return 0;
}
}
void infixtoPostfix(char* infix,char* postfix){
Stack s;
initStack(&s,100);//初始化方法要传入指针指向的地址,这里s取地址
char* p=infix;//要遍历的中缀表达式
char* q=postfix;//要遍历的后缀表达式
while(p!='\0'){
if(isdigit(*p)){
while(isdigit(*p)||*p=='.'){//???
*q=*p;
p++;
q++;
}
*q=' ';
q++;
}
else if(*p=='+'||*p=='-'||*p=='*'||*p=='/'){
int priority1=getPriority(*p);
while(!isEmpty(&s)&&isOperator(top(&s))&&getPriority(&s)>=priority1){
char op=pop(&s);
*p=op;
p++;
*p=' ';
p++;
}
push(&s,*p);//
p++;
}
else if(*p=='('){//左括号,直接入栈
push(&s,*p);
p++;
}
else if(*p==')'){//
while(!isEmpty(&s)&&top(&s)!=')'){
char op=pop(&s);
*q=op;
q++;
*q=' ';
q++;
}
if(!isEmpty(&s)&&top(&s)==')'){
pop(&s);
}
p++;//表达式后移
}
else{//表达式是空格,后移
p++;
}
}
while(!isEmpty(&s)){//最后如果栈不为空,依次出栈添加到后缀表达式
char op=pop(&s);
*q =op;
q++;
*q=' ';
q++;
}
*(q-1)='\0';//添加结束符
}
double operate(double num1, double num2, char op) {
switch (op) {
case '+':
return num1 + num2;
case '-':
return num1 - num2;
case '*':
return num1 * num2;
case '/':
return num1 / num2;
default:
printf("Invalid operator: %c\n", op);
exit(1);
}
}
double evaluate(char* postfix){
Stack s;
initStack(&s,100);
char *p=postfix;
while(*p!='\0'){
if(isdigit(*p)){
double num=*p- '0';
p++;
while(isdigit(*p)){
num=num*10+(*p- '0');
p++;
}
push(&s,num);
}
else if(*p=='+'||*p=='-'||*p=='*'||*p=='/'){
double num2=top(&s);
double num1=top(&s);
double reslust =operate(num1,num2,*p);
push(&s,reslust);
p++;
}
else{
p++;
}
}
return pop(&s);
}
int main()
{
char a[100];
char b[100];
scanf("%s",&a);
infixtoPostfix(a,b);
double result=evaluate(b);
printf("%g",result);
return 0;
}
【相关推荐】
命令:gcc -c hello.s -o hello.o
汇编器将hello.s翻译成机器语言指令,再将这些指令按照可重定向目标程序的格式储存,结果保存在hello.o二进制文件当中,如果我们打开hello.o会查看到一堆乱码,如下。