表示式求值(C實現,實現多括號,浮點數)---棧的實現以及運用。
阿新 • • 發佈:2019-01-03
剛學完棧的時候寫的,主要鍛鍊下棧的C實現吧!
//棧用單鏈表來實現
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<math.h>
#include<string.h>
struct Node1
{
char a;
struct Node1 *next;
};
struct Node2
{
double a;
struct Node2 *next;
};
typedef struct Node1 *Stack1;
typedef struct Node2 *Stack2;
Stack1 CreakStack1()
{
Stack1 S;
S = (Stack1)malloc(sizeof(Node1));
S->next = NULL;
return S;
}
Stack2 CreakStack2()
{
Stack2 S;
S = (Stack2)malloc(sizeof(Node2));
S->next = NULL;
return S;
}
void Push1(char c, Stack1 S)
{
Stack1 tmp;
tmp = (Stack1)malloc (sizeof(Node1));
tmp->a = c;
tmp->next = S->next;
S->next = tmp;
}
void Push2(double c, Stack2 S)
{
Stack2 tmp;
tmp = (Stack2)malloc(sizeof(Node1));
tmp->a = c;
tmp->next = S->next;
S->next = tmp;
}
void Pop1(Stack1 S)
{
Stack1 tmp ;
tmp = S->next;
S->next = tmp->next;
free (tmp);
}
void Pop2(Stack2 S)
{
Stack2 tmp;
tmp = S->next;
S->next = tmp->next;
}
char Top1(Stack1 S)
{
return(S->next->a);
}
double Top2(Stack2 S)
{
return(S->next->a);
}
bool Isempty1(Stack1 S)//這道題感覺沒什麼用!反正輸入合法!
{
return S->next == NULL;
}
bool Isempty2(Stack2 S)
{
return S->next == NULL;
}
char Prior[8][8] =
{ // 運算子優先順序表
// '+' '-' '*' '/' '(' ')' '#' '^'
/*'+'*/'>','>','<','<','<','>','>','<',
/*'-'*/'>','>','<','<','<','>','>','<',
/*'*'*/'>','>','>','>','<','>','>','<',
/*'/'*/'>','>','>','>','<','>','>','<',
/*'('*/'<','<','<','<','<','=',' ','<',
/*')'*/'>','>','>','>',' ','>','>','>',
/*'#'*/'<','<','<','<','<',' ','=','<',
/*'^'*/'>','>','>','>','<','>','>','>'
};
float Operate(float a, char c, float b)
{
switch (c)
{
case '+':return a + b;
case'-':return a - b;
case'*':return a*b;
case'/':return a / b;
case'^':return pow(a, b);
default:return 0;
}
}
char OP[] = { "+-*/()#^" }; //把可能遇到的8個運算元預先存到一個數組中
int In(char a) //判斷字元是否為運算元
{
int flag = 0;
for (int i = 0; i < 8; i++)
if (a == OP[i]) { flag = 1; continue; }
return flag;
}
int Ord(char a) //將運算元轉化為座標
{
for (int i = 0; i < 8; i++)
if (a == OP[i])return i;
}
char Precede(char a, char b) //返回運算元的優先順序
{
return(Prior[Ord(a)][Ord(b)]);
}
float Evaluate(char *Expression)
{
Stack1 S1 = CreakStack1();
Stack2 S2 = CreakStack2();
Push1('#', S1);
char cat[2] = "\0";
char digit[20] = ""; //從表示式陣列中接受運算元部分
strcat(Expression, "#");
if (*Expression == '-'); //對第一個數是負數情況的處理;負數只會出現在字串的第一個或者左括號的下一個哦!!!
Push2(0.0, S2);
while (!(*Expression == '#'&&Top1(S1) == '#'))
{
if (!In(*Expression))//運算元
{
cat[0] = *Expression;
strcat(digit, cat);
Expression++;
if (In(*Expression))
{
double Data = atof(digit);
Push2(Data, S2);
strcpy(digit, "\0");
}
}
else //操作符
{
if (*Expression == '(') //遇到負數的情況的處理;
{
if (*++Expression == '-')
Push2(0.0, S2); //壓入浮點數棧一個0;
Expression--; //回到左括號。
}
switch (Precede(Top1(S1), *Expression))
{
case'<':
Push1(*Expression, S1);
Expression++;
break;
case'=':
Pop1(S1);
Expression++;
break;
case'>':
char c = Top1(S1); Pop1(S1);
double a = Top2(S2); Pop2(S2);
double b = Top2(S2); Pop2(S2);
Push2(Operate(b, c, a), S2);
break;
}//switch
}//else
}//while
return(Top2(S2));
}
int main()
{
char s[200];
puts("請輸入表示式(括號在英文狀態下輸入)");
scanf("%s", s);
puts("該表示式的值為");
printf("%f\n\n", Evaluate(s));
system("pause");
}