數(shù)據(jù)結(jié)構(gòu)題目:棧

其實(shí)真正想做一個(gè)好的計(jì)算器會(huì)用到編譯原理狀態(tài)機(jī)少漆、狀態(tài)轉(zhuǎn)換相關(guān)知識(shí),這里我僅僅是對一些我能想到的情況進(jìn)行了處理硼被,還會(huì)有很多想不到的情況示损,編程任重而道遠(yuǎn)。

數(shù)據(jù)結(jié)構(gòu)題目:棧

題目:算術(shù)表達(dá)式求值

輸入中綴算術(shù)表達(dá)式嚷硫,如:5+(4-2)3屎媳,將其轉(zhuǎn)換成后綴表達(dá)式并輸出:542-3+,再對后綴表達(dá)式求值(本例結(jié)果為11)并將結(jié)果輸出论巍。
image

c:

#include "stdio.h"
#include "malloc.h"
#include "string.h"
#include "stdlib.h"

#define ERROR 0
#define SIZE 100

int temp=0;
int error=0;
typedef struct
{
    char data[SIZE];
    int top;
    int base;
}slink_c;

typedef struct
{
    double data[SIZE];
    int top;
    int base;
}slink_d;

void Initstack_c(slink_c *s)
{
    s->top = 0;
    s->base = 0;
}

void Initstack_d(slink_d *s)
{
    s->top = s->base = 0;
}

int Emptystack_c(slink_c *s)
{
    if(s->top == s->base)
        return(1);
    else
        return(0);
}

int Emptystack_d(slink_d *s)
{
    if(s->top == s->base)
        return(1);
    else
        return(0);
}

char Pop_c(slink_c *s)
{
    char e;
    if(s->data[s->top]=='#')
        return ERROR;
    else
    {
        e=s->data[s->top-1];
        s->top--;
    }
    return e;
}

double Pop_d(slink_d *s)
{
    double e;
    if(s->base == s->top)
        return ERROR;
    else
    {
        e=s->data[s->top-1];
        s->top--;
    }
    return e;
}

void Push_c(slink_c *s, char e)
{
    s->data[s->top]=e;
    s->top++;
}

void Push_d(slink_d *s, double e)
{
    s->data[s->top]=e;
    s->top++;
}

char Gettop_c(slink_c *s)
{
    if(s->top == s->base)
        return ERROR;
    return (s->data[s->top-1]);
}

double Gettop_d(slink_d *s)
{
    if(s->top == s->base)
        return ERROR;
    return (s->data[s->top-1]);
}

//判斷是不是一個(gè)數(shù)字
bool IsNumber(char x)
{
    if(x == '0' || x == '1' || x == '2' || x == '3' || x == '4' || x == '5' || x == '6' || x == '7' || x == '8' || x == '9')
        return (true);
    else
        return (false);
}

//判斷是不是一個(gè)符號(hào)
bool IsOperator(char x)
{
    if(x == '+' || x == '-' || x == '*' || x == '/' || x == '(' || x == ')'|| x == '#')
        return (true);
    else
        return (false);
}

//符號(hào)優(yōu)先級(jí)比較
int Precede (char x, char y)
{
    switch(x)
    {
        case '(':x=0;break;
        case '+':
        case '-':x=1;break;
        case '*':
        case '/':x=2;break;
    }
    switch(y)
    {
        case '+':
        case '-':y=1;break;
        case '*':
        case '/':y=2;break;
        case '(':y=3;break;
    }
    if (x >= y)
        return (1);
    else
        return (0);
}

//中綴轉(zhuǎn)后綴
void mid_post(char post[], char mid[])
{
    slink_c s1;
    int i=0, j=0;
    char ch;
    Initstack_c(&s1);
    Push_c(&s1,'#');
    if(mid[i] == '\0')
    {
        error = 1;
        printf("輸入錯(cuò)誤\n");
        return;
    }
    while(mid[i]!='\0')
    {
        if(IsNumber(mid[i]))
        {
            while((mid[i] >= '0'&&mid[i] <= '9')||mid[i] == '.')
            {
                post[j++] = mid[i];
                temp++;
                i++;
            }
            post[j++] = ' ';
            temp++;
        }
        else if(IsOperator(mid[i]))
        {
            switch(mid[i])
            {
                case '(':
                {
                    i++;
                    if(mid[i] == '-')
                    {
                        while(mid[i] != ')')
                        {
                            post[j++] = mid[i];
                            i++;
                            temp++;
                        }
                        post[j++] = ' ';
                        i++;
                        temp++;
                    }
                    else
                    {
                        i--;
                        Push_c(&s1,mid[i]);
                        i++;
                    }
                }break;
                case ')':
                {
                    ch = Pop_c(&s1);
                    do
                    {
                        post[j++] = ch;
                        temp++;
                        post[j++] = ' ';
                        temp++;
                        ch = Pop_c(&s1);
                    }while(ch != '(');
                    i++;
                }break;
                default :
                {
                    while(Precede(Gettop_c(&s1),mid[i]))
                    {
                        post[j++] = Pop_c(&s1);
                        temp++;
                        post[j++] = ' ';
                        temp++;
                    }
                    Push_c(&s1,mid[i]);
                    i++;
                }break;
            }
        }
        else if(mid[i] == ' ')
        {
            i++;
        }
        else
        {
            error = 1;
            printf("輸入錯(cuò)誤\n");
            break;
            return;
        }
    }
    while(Gettop_c(&s1) != '#')
    {
        post[j++] = Pop_c(&s1);temp++;
        post[j++] = ' ';temp++;
    }
}

//單獨(dú)表達(dá)式求值
double  Operate(double a, char t, double b)
{
    switch(t)
    {
        case '+': return a+b; break;
        case '-': return a-b; break;
        case '*': return a*b; break;
        case '/':
        {
            if(b == 0)
            {
                printf("除數(shù)為0烛谊,輸入錯(cuò)誤\n");
                return ERROR;
            }
            return a/b;
            break;
        }
        default:
        {
            printf("輸入錯(cuò)誤\n");
            return ERROR;
        }
    }
}

//后綴表達(dá)式求值
double postcount(char post[])
{
    slink_d s2;
    Initstack_d(&s2);
    char ch;
    int i=0,step=0,j=0;
    double a=0,s=0,b=0;
    ch = post[0];
    while(i<temp-1)
    {
        if(IsNumber(post[i]))
        {
            s=0;
            a=0;b=0;step=0;
            while(post[i]>='0'&&post[i]<='9'&&post[i]!='.'&&post[i]!=' ')
            {
                s=10*s+post[i]-48;
                i++;
            }
            if(post[i] == '.')
            {
                i++;
                while(post[i]>='0'&&post[i]<='9'&&post[i]!=' ')
                {
                    b=10*b+post[i]-48;
                    i++;
                    step++;
                }
                for(j=0; j<step; j++)
                {
                    b=b/10;
                }
            }
            a=s+b;
            Push_d(&s2,a);
            ch=post[++i];
        }
        if(IsOperator(post[i]))
        {
            if(post[i] == '-')
            {
                i++;
                if(post[i]>'0'&&post[i]<'9')
                {
                    s=0;
                    a=b=step=0;
                    while(post[i]>='0'&&post[i]<='9'&&post[i]!='.'&&post[i]!=' ')
                    {
                        s=10*s+post[i]-48;
                        i++;
                    }
                    if(post[i] == '.')
                    {
                        i++;
                        while(post[i]>='0'&&post[i]<='9'&&post[i]!=' ')
                        {
                            b=10*b+post[i]-48;
                            i++;
                            step++;
                        }
                        for(j=0; j<step; j++)
                        {
                            b=b/10;
                        }
                    }
                    a=-(s+b);
                    Push_d(&s2,a);
                    ch=post[++i];
                }
                else
                {
                    b=Pop_d(&s2);
                    a=Pop_d(&s2);
                    Push_d(&s2,Operate(a,ch,b));
                    i+=1;
                    ch = post[i];
                }
            }
            else
            {
                b=Pop_d(&s2);
                a=Pop_d(&s2);
                Push_d(&s2,Operate(a,ch,b));
                i+=2;
                ch = post[i];
            }
        }
    }
    return (Gettop_d(&s2));
}


int main()
{
    char mid[100];
    char post[100];
    char c;
    double val;

    printf("請輸入想要計(jì)算的中綴表達(dá)式\n:");
    gets(mid);
    printf("\n%s = \n",mid);
    mid_post(post, mid);
    if(error == 0)
    {
        for(int k=0;k<temp;k++)
            printf("%c",post[k]);
        printf("=\n");
    }
    else
        printf("請檢查您的輸入\n");
    if(error == 0)
    {
        val = postcount(post);
        printf("%lf\n",val);
    }
    return 0;
}

java:

import java.util.Scanner;
import java.util.Stack;

/**
 *@author movis
 */
public class Main {
    
    static boolean errorflag = true;    //檢錯(cuò)旗幟,檢驗(yàn)是否輸入違法
    
    public static void main(String[] args) {
        String input;
        StringBuffer stmp;
        String mid ;
        String post;
        double output = 0;
        String cont;                    //繼續(xù)旗幟嘉汰,控制是否繼續(xù)
        
        Scanner in = new Scanner(System.in);
        do {
            stmp = new StringBuffer("");
            System.out.println("請輸入表達(dá)式:");
            input = in.nextLine();
            //刪除輸入中多余的空格
            for(int i=0; i<input.length(); i++) {
                if(!IsNumber(input.charAt(i)) && !IsOperator(input.charAt(i)))
                    errorflag = false;
                if(input.charAt(i) != ' ')
                    stmp.append(input.charAt(i));
            }
            if(!errorflag)
                System.out.println("輸入了違法字符丹禀,輸入錯(cuò)誤");
            mid = stmp.toString();
            if(mid.length() == 0) {
                errorflag = false;
                System.out.println("輸入為空,輸入錯(cuò)誤");
            }
            if(!IsNumber(mid.charAt(0))) {
                errorflag = false;
                System.out.println("輸入違法式子,輸入錯(cuò)誤");
            }
            
            //中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式
            post = mid2post(mid).toString();
            
            //后綴表達(dá)式求值
            output = getResult(post);
            
            if(errorflag) {
                System.out.println("輸入的中綴表達(dá)式為:"+mid);
                System.out.println("其對應(yīng)的后綴表達(dá)式為:"+post);
                System.out.println("結(jié)果為:"+output);
            }
            
            System.out.println("是否繼續(xù)双泪?請輸入Y/N");
            cont = in.nextLine();
            while(!cont.equals("Y") && !cont.equals("N")) {
                System.out.println("輸入錯(cuò)誤持搜,是否繼續(xù)?請輸入Y/N");
                cont = in.nextLine();
            }
        }while(cont.equals("Y"));
        
        in.close();
    }
    
    //判斷是否是一個(gè)數(shù)
    public static boolean IsNumber(char x) {
        if(x == '0' || x == '1' || x == '2' || x == '3' || x == '4' || x == '5' || x == '6' || x == '7' || x == '8' || x == '9')
            return true;
        else
            return false;
    }
    
    //判斷是否是一個(gè)符號(hào)
    public static boolean IsOperator(char x) {
        if(x == '+' || x == '-' || x == '*' || x == '/' || x == '(' || x == ')'|| x == '#'|| x == '.')
            return true;
        else
            return false;
    }
    
    //確定符號(hào)優(yōu)先級(jí)
    public static boolean priority(char x, char y) {
        int x1 = 0, y1 = 0;
        switch(x) {
        case '+': x1 = 1;break;
        case '-': x1 = 1;break;
        case '*': x1 = 2;break;
        case '/': x1 = 2;break;
        case '(': x1 = 0;break;
        default: x1 = 0;break;
        }
        switch(y) {
        case '+': y1 = 1;break;
        case '-': y1 = 1;break;
        case '*': y1 = 2;break;
        case '/': y1 = 2;break;
        case '(': y1 = 3;break;
        default: y1 = 0;break;
        }
        if(x1 >= y1)
            return true;
        else
            return false;
    }
    
    //中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式
    public static StringBuffer mid2post(String mid) {
        StringBuffer post = new StringBuffer("");
        int i = 0;
        char ch;
        Stack<Character> cs = new Stack<Character>();
        
        cs.push('#');
        while(i < mid.length()) {
            if(IsNumber(mid.charAt(i))) {
                while((mid.charAt(i) >= '0' && mid.charAt(i) <= '9') || mid.charAt(i) == '.') {
                    post.append(mid.charAt(i));
                    i++;
                    if(i == mid.length())
                        break;
                }
                post.append(' ');
            }
            else if(IsOperator(mid.charAt(i))) {
                switch(mid.charAt(i)) {
                case '(':{
                    i++;
                    if(mid.charAt(i) == '-') {
                        while(mid.charAt(i) != ')') {
                            post.append(mid.charAt(i));
                            i++;
                        }
                        post.append(' ');
                        i++;
                    }else {
                        i--;
                        cs.push(mid.charAt(i));
                        i++;
                    }
                }break;
                case ')':{
                    ch = cs.pop();
                    do {
                        post.append(ch);
                        post.append(' ');
                        ch = cs.pop();
                    }while(ch != '(');
                    i++;
                }break;
                default:{
                    while(priority(cs.peek(), mid.charAt(i))) {
                        post.append(cs.pop());
                        post.append(' ');
                        if(cs.peek() == '#')
                            break;
                    }
                    cs.push(mid.charAt(i));
                    i++;
                }break;
                }
            }else {
                System.out.println("輸入錯(cuò)誤焙矛!");
                return null;
            }
        }
        while(cs.peek() != '#') {
            post.append(cs.pop());
            post.append(' ');
        }
        
        return post;
    }
    
    //后綴表達(dá)式求值
    public static double getResult(String post) {
        double r = new Double(0);
        Stack<Double> ds = new Stack<Double>();
        int i = 0;
        int step = 0;               //控制小數(shù)的數(shù)值轉(zhuǎn)換
        double s = 0;               //控制整數(shù)的數(shù)值
        double a, b;                //b控制小數(shù)的數(shù)值,a控制整個(gè)數(shù)的數(shù)值
        
        while(i < post.length()) {
            if(IsNumber(post.charAt(i))) {
                a = 0;
                s = 0;
                b = 0;
                step = 0;
                while(IsNumber(post.charAt(i))) {
                    s = 10*s+post.charAt(i) - 48;
                    i++;
                }
                if(post.charAt(i) == '.') {
                    i++;
                    while(IsNumber(post.charAt(i))) {
                        b = 10*b+post.charAt(i) - 48;
                        i++;
                        step++;
                    }
                    for(int j=0; j<step; j++) {
                        b /= 10;
                    }
                }
                a = s+b;
                ds.push(a);
                
            }else if(IsOperator(post.charAt(i)) && post.charAt(i) != '.') {
                b = ds.pop();
                if(ds.isEmpty()) {
                    System.out.println("輸入錯(cuò)誤葫盼!");
                    errorflag = false;
                    return 0;
                }
                a = ds.pop();
                ds.push(calculate(a, post.charAt(i), b));
                i++;
            }else {
                i++;
            }  
        }
        r = ds.pop();
        
        return (r+0);
    }
    
    public static double calculate(double a, char t, double b) {
        double r = 0;
        switch(t) {
        case '+': r = a+b; break;
        case '-': r = a-b; break;
        case '*': r = a*b; break;
        case '/': {
            if(b == 0) {
                errorflag = false;
                return 0;
            }else {
                r = a/b;
                break;
            }
        }
        default: {
            errorflag = false;
        }
        }
        return r;
    }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市村斟,隨后出現(xiàn)的幾起案子贫导,更是在濱河造成了極大的恐慌,老刑警劉巖蟆盹,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件孩灯,死亡現(xiàn)場離奇詭異,居然都是意外死亡逾滥,警方通過查閱死者的電腦和手機(jī)峰档,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來寨昙,“玉大人讥巡,你說我怎么就攤上這事√蚰模” “怎么了尚卫?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長尸红。 經(jīng)常有香客問我吱涉,道長,這世上最難降的妖魔是什么外里? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任怎爵,我火速辦了婚禮,結(jié)果婚禮上盅蝗,老公的妹妹穿的比我還像新娘鳖链。我一直安慰自己,他們只是感情好墩莫,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布芙委。 她就那樣靜靜地躺著,像睡著了一般狂秦。 火紅的嫁衣襯著肌膚如雪灌侣。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天裂问,我揣著相機(jī)與錄音侧啼,去河邊找鬼牛柒。 笑死,一個(gè)胖子當(dāng)著我的面吹牛痊乾,可吹牛的內(nèi)容都是我干的皮壁。 我是一名探鬼主播,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼哪审,長吁一口氣:“原來是場噩夢啊……” “哼蛾魄!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起湿滓,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤滴须,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后茉稠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡把夸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年而线,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片恋日。...
    茶點(diǎn)故事閱讀 38,599評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡膀篮,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出岂膳,到底是詐尸還是另有隱情誓竿,我是刑警寧澤,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布谈截,位于F島的核電站筷屡,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏簸喂。R本人自食惡果不足惜毙死,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望喻鳄。 院中可真熱鬧扼倘,春花似錦、人聲如沸除呵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽颜曾。三九已至纠拔,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間泛豪,已是汗流浹背绿语。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工秃症, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人吕粹。 一個(gè)月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓种柑,卻偏偏與公主長得像,于是被迫代替她去往敵國和親匹耕。 傳聞我的和親對象是個(gè)殘疾皇子聚请,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 官網(wǎng) 中文版本 好的網(wǎng)站 Content-type: text/htmlBASH Section: User ...
    不排版閱讀 4,370評論 0 5
  • 基礎(chǔ)知識(shí) 基本概念 常見數(shù)據(jù)結(jié)構(gòu) 棧和隊(duì)列 棧Stack 隊(duì)列Queue 樹和堆 樹的定義 樹(tree)是包含n...
    passwd_閱讀 1,455評論 0 2
  • 棧的規(guī)則 先進(jìn)后出。如:依次入棧順序?yàn)椋篈,B,C,D;怎出棧順序?yàn)椋篋,C,B,A . 二叉樹和表達(dá)式 表達(dá)式的...
    zhangivon閱讀 819評論 0 0
  • 第一部分Common Lisp介紹第1章 介紹一下Lisp你在學(xué)的時(shí)候覺得已經(jīng)明白了稳其,寫的時(shí)候更加確信了解了驶赏,教別...
    geoeee閱讀 2,927評論 5 8
  • 養(yǎng)生之道功在止念,若然念頭不止既鞠,養(yǎng)生的功效便會(huì)大打折扣煤傍。 何謂【念】? 【念】是由于無明升起時(shí)沒有覺察嘱蛋,以致于思緒...
    覚明閱讀 784評論 2 9