簡單計算器 (關於棧的一種應用)

haixinjiazu發表於2019-05-10

題目:簡單計算器
讀入一個只包含 +, -, *, / 的非負整數計算表示式,計算該表示式的值。
Input
測試輸入包含若干測試用例,每個測試用例佔一行,每行不超過200個字元,整數和運算子之間用一個空格分隔。沒有非法表示式。當一行中只有0時輸入結束,相應的結果不要輸出。
Output
對每個測試用例輸出1行,即該表示式的值,精確到小數點後2位。

樣例:
Sample Input
1 + 2
4 + 2 * 5 – 7 / 11
0
Sample Output
3.00
13.36

思路:利用棧,建立兩個棧,一個是用來存數的,一個用來存運算子的,因為運算子之間是有優先順序關係,所以要定義一個函式用來判斷其優先順序,當後來即將存的優先順序高於棧頂的,則將其存入棧頂,如果後來的優先順序是低於棧頂的,則要讓運算子的棧的棧頂與存數的棧的前兩個,進行運算,然後把結果再存入存數的棧頂。依次這樣,最後存數的棧剩下的那個棧頂就是最後的結果;

新技巧:1:這裡是棧的一種新的用法,即關於優先順序問題的處理,可以通過滿足其優先順序關係就進棧,不滿足則進行一系列操作,就是說有關優先順序的問題可以考慮用棧來處理;
2:關於優先順序的問題,如果無法用數值等來比較,則自己定義函式來將優先順序排出來,如果很雜的時候,在情況不多的時候可以一個一個情況列出來;

程式碼:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct Node {
    double val;
    char ch;
    Node *next;
};

struct stacks{
    Node *top;
    Node *bottom;
};

int compere(char ch1,char ch2);
double sumulete (double a,double b,char x);

int main()
{
    double sum,b1,b2,b3;
    int tag,i,num;
    char ch,a[205];
    while(gets(a)!=NULL)
    {
        if(strcmp(a,"0")==0)
            break;
        stacks *st_number=(stacks *)malloc(sizeof(stacks ));
        st_number->top=(Node *)malloc(sizeof(Node ));
        st_number->top->next=nullptr;
        st_number->bottom=st_number->top;

        stacks *st_sign=(stacks *)malloc(sizeof(stacks ));
        st_sign->top=(Node *)malloc(sizeof(Node ));
        st_sign->top->ch=`#`;
        st_sign->top->next=nullptr;
        st_sign->bottom=st_sign->top;

        tag=0;sum=0;num=strlen(a);
        for(i=0;i<=num;i++)
        {
            if(a[i]==` `)
                continue;
            else if(a[i]<=`9`&&a[i]>=`0`)
            {
                sum=sum*10+a[i]-`0`;
                tag=1;
            }
            else
            {
                if(tag)
                {
                    Node *temp=(Node *)malloc(sizeof(Node ));
                    temp->val=sum;
                    temp->next=st_number->top;
                    st_number->top=temp;

                    tag=0;sum=0;
                }
                if(compere(st_sign->top->ch,a[i])<0)
                {
                    Node *temp=(Node *)malloc(sizeof(Node ));
                    temp->ch=a[i];
                    temp->next=st_sign->top;
                    st_sign->top=temp;
                }
                else if(compere(st_sign->top->ch,a[i])>0)
                {
                    b1=st_number->top->val;
                    Node *tt=st_number->top;
                    st_number->top=tt->next;
                    free(tt);
                    b2=st_number->top->val;
                    b3=sumulete(b1,b2,st_sign->top->ch);
                    st_number->top->val=b3;
                    Node *ss=st_sign->top;
                    st_sign->top=ss->next;
                    free(ss);
                    i--;
                }
                else
                {
                    Node *tt=st_sign->top;
                    st_sign->top=tt->next;
                    free(tt);
                }
            }
        }
        printf("%.2f
",st_number->top->val);
    }
    return 0;
}

double sumulete (double a,double b,char x)
{
    double t;
    switch(x)
    {
        case `*`:t=a*b;break;
        case `/`:t=b/a;break;
        case `+`:t=a+b;break;
        case `-`:t=b-a;break;
    }
    return t;
}

int compere(char ch1,char ch2)
{
    int tag;
    if(ch2==` `)
    {
        if(ch1==`#`)
            tag=-1;
        else
            tag=1;
    }
   else  if(ch1==`+`||ch1==`-`)
    {
        if(ch2==`+`||ch2==`-`||ch2==`)`)
            tag=1;
        else
            tag=-1;
    }
   else  if(ch1==`*`||ch1==`/`)
    {
        if(ch2==`(`)
            tag=-1;
        else
            tag=1;
    }
   else  if(ch1==`(`)
    {
        if(ch2==`)`)
            tag=0;
        else
            tag=-1;
    }
   else  if(ch1==`)`)
        tag=1;
   else  if(ch1==`#`)
        tag=-1;
    return tag;
}

相關文章