因為做二叉樹非遞歸的前後中遍歷,用到棧的方法。xpp說那就干脆把四則運算,逆波蘭式 棧的實現做了。
這是參考別人的程序寫的,注釋比較亂。而且這個是直接實現計算機計算的四則運算,沒有將逆波蘭的表達式打印出來。今天腰太酸了,明天改一改,把逆波蘭式打印出來噻333333.棧還有迷宮算法是不是???現在腦子裡之前看的非遞歸遍歷都想不起來了我擦
#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"
#include"string.h"
#define MAX_OPE_LEN 10
#define MAX_STRING_LEN 100
#define MAX_STACK_LEN 100
//
typedef struct operater
{
char name;
int pior;
int opernum;
}Operater;
Operater opStack[MAX_OPE_LEN];
int opStacktop=-1;//外加一個指示棧頂的數,這也挺奇葩的
double numStack[MAX_STACK_LEN];
int numStacktop=-1;
int getPior(char name)
{
if (name=='('||name==')')//注意括號的優先級
{ return 0;}
if (name=='+'||name=='-')
{ return 1;}
if(name=='*'||name=='/')
{ return 2;}
if(name=='!')
{ return 3;}
exit(1);//其他情況則直接退出
}
int getopernum(char name)
{
if(name=='+'||name=='-'||name=='*'||name=='/')
{ return 2;}
if(name=='!')
{ return 1;}
if(name=='('||name==')')//特別注意括號的操作數為0;
{ return 0;}
exit(1);
}
void pushoperater(Operater op)//入棧操作的是一個 運算符
{
if (opStacktop='0'&&*s<='9')
{
string[j++]=*s;
s++;
}
if (*s=='.')
{
string[j++]=*s;
s++;
while(*s>='0'&&*s<='9')
{
string[j++]=*s;
s++;
}
}
(*i)=(*i)+j;
string[j]='\0';//表示字符結束
return atof(string);//將這個字符轉化為num
}
double operater2num(Operater op)
{
double num2=popnum();
double num1=popnum();
if (op.name=='+')
{return num1+num2;}
if (op.name=='-')
{return num1-num2;}
if(op.name=='*')
{return num1*num2;}
if(op.name=='/')
{return num1/num2;}
{exit(1);}
}
//=============這部分也是比較難的,暫時可以不看啊===========
double operater1num(Operater op)//非操作?為何是這樣??
{
double num = popnum();
if (op.name == '!')
{
double result = 1;
while (num > 1)
{
result *= num;
num--;
}
return result;
}
exit(1);
}
double operater(Operater op)
{
if (op.opernum==2)
{return operater2num(op);}
if (op.opernum==1)
{return operater1num(op);}
exit(1);
}
//進入復雜的主函數操作
int main()
{
char string[MAX_STRING_LEN ];
printf("輸入中綴運算表達式:\n");
scanf("%s",string);//注意scanf的用法,輸入到string中。%S表明輸入的是字符串啊啊啊啊啊啊,%f,輸入的是float型啊啊啊啊,並且沒有該死的\n
Operater op,opTop;//後者為棧頂運算符,這個用來表示操作符到了最底部
opTop.name='#';
opTop.opernum=0;
opTop.pior=0;
pushoperater(opTop);
int i=0;
for(i;string[i]!='\0'&&string[i]!='=';)
{
if (string[i]>='0'&&string[i]<='9')
pushnum(getNumfromString(&string[i],&i));//把從i開始的數字都取完,轉成num壓入棧
else
{
op.name=string[i];
op.opernum=getopernum(op.name);
op.pior=getPior(op.name);
opTop=popoperater();//把操作符的棧頂操作符與 新發現的操作符對比
if (op.name=='(')
{
pushoperater(opTop);
pushoperater(op);
}
else if (op.name==')')
{
while(opTop.name!='(')//只要沒到左括號,將這之間的操作數 與numStack中的Num取出來實行運算,運算結果壓入numStack
{
pushnum(operater(opTop));
opTop=popoperater();
}
}
else
{
if (opTop.name!='#'&&op.pior<=opTop.pior)
{
pushnum(operater(opTop));
}
else
{
pushoperater(opTop);
}
pushoperater(op);
}
i++;//因為操作符是一個一個的字符,上面字符與數字轉換的時候,可能不是一個一個的加的
}
//string已經轉換完了,這個時候操作符棧還有剩,則全部取出來操作
}
while((opTop = popoperater()).name != '#')
{
pushnum(operater(opTop));
}
printf("%f\n", popnum());
system("pause");
return 0;
} 