1. 程式人生 > >表示式求值(C實現,實現多括號,浮點數)---棧的實現以及運用。

表示式求值(C實現,實現多括號,浮點數)---棧的實現以及運用。

剛學完棧的時候寫的,主要鍛鍊下棧的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"); }