青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

       棧的應用很廣泛,原書只講解了表達式求值,那我也就只寫這些。其實,棧的最大的用途是解決回溯問題,這也包含了消解遞歸;而當你用棧解決回溯問題成了習慣的時候,你就很少想到用遞歸了,比如迷宮求解。另外,人的習慣也是先入為主的,比如樹的遍歷,從學的那天開始,就是遞歸算法,雖然書上也教了用棧實現的方法,但應用的時候,你首先想到的還是遞歸;當然了,如果語言本身不支持遞歸(如BASIC),那棧就是唯一的選擇了——好像現在的高級語言都是支持遞歸的。

    如下是表達式類的定義和實現,表達式可以是中綴表示也可以是后綴表示,用頭節點數據域里的type區分,這里有一點說明的是,由于單鏈表的賦值函數,我原來寫的時候沒有復制頭節點的內容,所以,要是在兩個表達式之間賦值,頭節點里存的信息就丟了。你可以改寫單鏈表的賦值函數來解決這個隱患,或者你根本不不在兩個表達式之間賦值也行。

#ifndef Expression_H

#define Expression_H

 

#include "List.h"

#include "Stack.h"

 

#define INFIX 0

#define POSTFIX 1

#define OPND 4

#define OPTR 8

 

template <class Type> class ExpNode

{

public:

       int type;

       union { Type opnd; char optr;};

       ExpNode() : type(INFIX), optr('=') {}

       ExpNode(Type opnd) : type(OPND), opnd(opnd) {}

       ExpNode(char optr) : type(OPTR), optr(optr) {}

};

 

template <class Type> class Expression : List<ExpNode<Type> >

{

public:

       void Input()

       {

              MakeEmpty(); Get()->type =INFIX;

              cout << endl << "輸入表達式,以=結束輸入" << endl;

              Type opnd; char optr = ' ';

              while (optr != '=')

              {

                     cin >> opnd;

                     if (opnd != 0)

                     {

                            ExpNode<Type> newopnd(opnd);

                            LastInsert(newopnd);

                     }

                     cin >> optr;

                     ExpNode<Type> newoptr(optr);

                     LastInsert(newoptr);

                    

              }

       }

 

       void Print()

       {

              First();

              cout << endl;

              for (ExpNode<Type> *p = Next(); p != NULL; p = Next() )

              {

                     switch (p->type)

                     {

                     case OPND:

                            cout << p->opnd; break;

                     case OPTR:

                            cout << p->optr; break;

                     default: break;

                     }

                     cout << ' ';

              }

              cout << endl;

       }

 

       Expression & Postfix() //將中綴表達式轉變為后綴表達式

       {

              First();

              if (Get()->type == POSTFIX) return *this;

              Stack<char> s; s.Push('=');

              Expression temp;

              ExpNode<Type> *p = Next();

              while (p != NULL)

              {

                     switch (p->type)

                     {

                     case OPND:

                            temp.LastInsert(*p); p = Next(); break;

                     case OPTR:

                            while (isp(s.GetTop()) > icp(p->optr) )

                            {

                                   ExpNode<Type> newoptr(s.Pop());

                                   temp.LastInsert(newoptr);

                            }

                            if (isp(s.GetTop()) == icp(p->optr) )

                            {

                                   s.Pop(); p =Next(); break;

                            }

                            s.Push(p->optr); p = Next(); break;

                     default: break;

                     }

              }

              *this = temp;

              pGetFirst()->data.type = POSTFIX;

              return *this;

       }

 

       Type Calculate()

       {

              Expression temp = *this;

              if (pGetFirst()->data.type != POSTFIX) temp.Postfix();

              Stack<Type> s; Type left, right;

              for (ExpNode<Type> *p = temp.Next(); p != NULL; p = temp.Next())

              {

                     switch (p->type)

                     {

                     case OPND:

                            s.Push(p->opnd); break;

                     case OPTR:

                            right = s.Pop(); left = s.Pop();

                            switch (p->optr)

                            {

                            case '+': s.Push(left + right); break;

                            case '-': s.Push(left - right); break;

                            case '*': s.Push(left * right); break;

                            case '/': if (right != 0) s.Push(left/right); else return 0; break;

//                          case '%': if (right != 0) s.Push(left%right); else return 0; break;

//                          case '^': s.Push(Power(left, right)); break;

                            default: break;

                            }

                     default: break;

                     }

              }

              return s.Pop();

       }

 

private:

       int isp(char optr)

       {

              switch (optr)

              {

              case '=': return 0;

              case '(': return 1;

              case '^': return 7;

              case '*': return 5;

              case '/': return 5;

              case '%': return 5;

              case '+': return 3;

              case '-': return 3;

              case ')': return 8;

              default: return 0;

              }

       }

 

       int icp(char optr)

       {

              switch (optr)

              {

              case '=': return 0;

              case '(': return 8;

              case '^': return 6;

              case '*': return 4;

              case '/': return 4;

              case '%': return 4;

              case '+': return 2;

              case '-': return 2;

              case ')': return 1;

              default: return 0;

              }

       }

 

};

 

#endif

幾點說明

l         表達式用單鏈表儲存,你可以看到這個鏈表中既有操作數又有操作符,如果你看過我的《如何在一個鏈表中鏈入不同類型的對象》,這里的方法也是對那篇文章的補充。

l         輸入表達式時,會將原來的內容清空,并且必須按照中綴表示輸入。如果你細看一下中綴表達式,你就會發現,除了括號,表達式的結構是“操作數”、“操作符”、“操作數”、……“操作符(=)”,為了統一這個規律,同時也為了使輸入函數簡單一點,規定括號必須這樣輸入“0(”、“)0”;這樣一來,“0”就不能作為操作數出現在表達式中了。因為我沒有在輸入函數中增加容錯的語句,所以一旦輸錯了,那程序就“死”了。

l         表達式求值的過程是,先變成后綴表示,然后用后綴表示求值。因為原書講解的是這兩個算法,并且用這兩個算法就能完成中綴表達式的求值,所以我就沒寫中綴表達式的直接求值算法。具體算法說明參見原書,我就不廢話了。

l         Calculate()注釋掉的兩行,“%”是因為只對整型表達式合法,“^”的Power()函數沒有完成。

Posted on 2005-12-15 12:34 艾凡赫 閱讀(1106) 評論(0)  編輯 收藏 引用 所屬分類: C++
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久久久国产成人精品亚洲午夜| 亚洲欧美日韩精品久久| 久久久久久亚洲精品中文字幕| 亚洲最黄网站| 亚洲一区二区三区影院| 午夜精品久久久久久99热软件| 午夜免费在线观看精品视频| 亚洲综合清纯丝袜自拍| 久久av一区二区三区| 老牛影视一区二区三区| 欧美人与性动交α欧美精品济南到| 欧美日韩一区二区三区四区五区| 国产精品福利影院| 狠狠干综合网| 一区二区三区日韩精品| 欧美亚洲系列| 欧美激情自拍| 亚洲一区二区3| 久色婷婷小香蕉久久| 欧美日本韩国在线| 狠狠色丁香婷婷综合影院| 一本色道久久综合亚洲91| 欧美在线影院| 亚洲乱码视频| 久久久综合网站| 国产精品久久久久久久浪潮网站| 影音先锋亚洲一区| 午夜久久美女| 亚洲日韩欧美视频| 欧美在线视屏| 国产精品免费在线| 日韩午夜在线观看视频| 久久亚洲精品一区二区| 制服诱惑一区二区| 欧美久久久久| 亚洲激情第一页| 久久久久久伊人| 亚洲一区二区在线播放| 国产人成一区二区三区影院| 国模叶桐国产精品一区| 一区二区三区蜜桃网| 欧美激情第8页| 久久综合婷婷| 激情欧美一区二区三区| 久久国内精品自在自线400部| 亚洲精选在线| 欧美国产日本韩| 亚洲第一区在线观看| 开元免费观看欧美电视剧网站| 亚洲视频视频在线| 国产精品v欧美精品v日本精品动漫 | 国产片一区二区| 国产精品色在线| 日韩一二三区视频| 欧美激情女人20p| 久久视频一区二区| 尤妮丝一区二区裸体视频| 久久精品国产清自在天天线| 亚洲自拍偷拍福利| 国产女主播一区二区| 先锋a资源在线看亚洲| 亚洲午夜国产一区99re久久 | 国产亚洲精品久| 久久成人资源| 午夜一区二区三区不卡视频| 国产精品美女视频网站| 午夜精品视频| 欧美亚洲视频在线观看| 国产日韩欧美一区二区三区在线观看| 午夜精品久久久久久久久久久久| 中日韩在线视频| 国产精品免费一区二区三区观看| 午夜精品区一区二区三| 亚洲欧美国产一区二区三区| 国产女人精品视频| 久久亚洲免费| 欧美激情第1页| 亚洲欧美日韩精品久久久| 午夜激情久久久| 在线看片欧美| 亚洲精品专区| 国产午夜精品理论片a级大结局| 久久亚洲精品一区| 欧美精品一区二区三区很污很色的 | 国产精品久久久久免费a∨大胸| 亚洲欧美日韩综合国产aⅴ| 欧美在线免费视频| 亚洲乱码国产乱码精品精可以看 | 欧美a级大片| 欧美日韩亚洲成人| 久久精品国产69国产精品亚洲| 久久久久国产精品午夜一区| 日韩午夜av在线| 亚洲免费在线精品一区| 亚洲国产二区| 亚洲一区免费| 亚洲国产精彩中文乱码av在线播放| 91久久精品日日躁夜夜躁国产| 国产精品伦理| 亚洲激情一区二区| 国产在线不卡精品| 日韩一区二区福利| 亚洲二区视频在线| 香蕉久久夜色精品国产| 9人人澡人人爽人人精品| 欧美一区二区高清在线观看| 亚洲麻豆视频| 久久婷婷久久| 亚洲国产婷婷香蕉久久久久久99| 欧美精品一区二区久久婷婷| 亚洲欧美制服另类日韩| 欧美大片网址| 久久国产主播| 国产精品久久亚洲7777| 欧美激情一区二区| 黄色成人在线网址| 国产精品99久久久久久宅男 | 国产精品久久久久久久久久久久久| 欧美成年人视频网站| 国产一区二区电影在线观看 | 亚洲欧美日韩天堂| 欧美日韩在线第一页| 亚洲国产精品悠悠久久琪琪| 樱桃国产成人精品视频| 欧美亚洲视频在线观看| 欧美一区二区免费| 国产精品视频一区二区三区| 亚洲人体影院| 亚洲另类春色国产| 欧美激情网站在线观看| 免费观看不卡av| ●精品国产综合乱码久久久久| 欧美一区二区在线播放| 欧美一区视频在线| 国产日韩欧美综合精品| 亚洲在线观看视频| 欧美在线视频免费| 国产日韩精品综合网站| 欧美一区二区三区久久精品茉莉花 | 一区二区三区产品免费精品久久75 | 亚洲福利av| 亚洲精品久久在线| 欧美国产三级| 日韩视频免费大全中文字幕| 亚洲九九爱视频| 欧美日本免费一区二区三区| 日韩亚洲欧美综合| 午夜精品免费在线| 国产自产在线视频一区| 久久综合九色综合久99| 亚洲国产精品va在看黑人| 夜夜爽www精品| 国产精品九九| 香蕉久久夜色精品国产| 欧美国内亚洲| 亚洲一区尤物| 激情偷拍久久| 欧美理论在线播放| 亚洲一区日韩在线| 久久综合五月| 99热精品在线| 国产亚洲欧美日韩在线一区| 久久一区欧美| 野花国产精品入口| 久久久一二三| 一区二区三区久久久| 国产亚洲欧美日韩一区二区| 久久综合久久综合久久综合| 永久久久久久| 亚洲午夜精品久久久久久浪潮| 欧美在线免费视屏| 在线精品国产欧美| 欧美日韩三级一区二区| 欧美在线你懂的| 亚洲人成毛片在线播放女女| 欧美伊人久久大香线蕉综合69| 亚洲国产美女精品久久久久∴| 国产精品扒开腿做爽爽爽视频| 亚洲尤物在线视频观看| 亚洲国产合集| 久久久青草青青国产亚洲免观| 亚洲久久一区| 一区在线电影| 国产伦理一区| 欧美日韩国产精品成人| 久久精品国产第一区二区三区最新章节 | 国产亚洲亚洲| 欧美日韩另类丝袜其他| 久久偷窥视频| 欧美一区二区在线看| 99精品国产99久久久久久福利| 久久免费视频在线| 亚洲欧美制服中文字幕| 99精品视频一区| 亚洲激情六月丁香| 韩日午夜在线资源一区二区| 国产精品午夜在线| 欧美性一二三区| 欧美日韩成人精品| 欧美电影免费观看大全|