• <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>
            隨筆 - 60, 文章 - 0, 評論 - 197, 引用 - 0
            數據加載中……

            用 C++ 實現的加、減、乘、除表達式計算

            前些日子面試一個開發工作,考官出了這么一筆試題目,要我寫出實現過程, 思量半天,終于
            用 C++ 完成,現將代碼貼出,與諸同道共分享。

            // 頭文件 Calc.h
            #ifndef __CALC_H__
            #define __CALC_H__

            #include <stack>

            #define ascii_int(x) (x >= 0x30 && x <= 0x39) ? (x - 0x30) : (x)
            const int GREATER =  1;
            const int EQUAL   =  0;
            const int LESS    = -1;

            class Calculate {
            public:
              int  evaluteExpr(char *exp);

            private:
              int  getLevel(char ch);
              bool isOperator(char ch);
              int  compareOpteratorLevel(char inputChar, char optrStackTop);
              int  calc(int num1, int num2, char op);
              void evaluate(char ch);

            private:
              std::stack<int>  _opnd_stack;
              std::stack<char> _optr_stack;
              static char _optr[];
              static int  _level[];
            };

            #endif


            // 頭文件的實現代碼 Calc.cxx
            #include "Calc.h"

            char Calculate::_optr[] = {'#', '(', '+', '-', '*', '/', ')'};
            int Calculate::_level[] = { 0,   1,   2,   2,   3,   3,   4 };

            // Get current operator level for calculating
            int Calculate::getLevel(char ch) {
              for (int i = 0; *(_optr+i) != '\0'; ++i)
                if (*(_optr+i) == ch)
                  return *(_level+i);
            }

            // Calculate the operands
            int Calculate::calc(int num1, int num2, char op) {
              switch (op)
                {
                case '+':
                  return num1 + num2;
                case '-':
                  return num1 - num2;
                case '*':
                  return num1 * num2;
                case '/':
                  return num1 / num2;
                }
            }

            // judge inputing character is operator or not
            bool Calculate::isOperator(char ch) {
              for (char *p = _optr; *p != '\0'; ++p)
                if (*p == ch)
                  return true;

              return false;
            }

            // Compare level of input operator and the top operator of operator stack
            int Calculate::compareOpteratorLevel(char inputChar, char optrStackTop) {
            //   if (inputChar == '(' && optrStackTop == ')')
            //     return EQUAL;
            //   else
              if (inputChar == '(')
                return GREATER;

              if (inputChar == ')' && optrStackTop == '(')
                return EQUAL;
              else if (inputChar == ')')
                return LESS;

              if (inputChar == '#' && optrStackTop == '#')
                return EQUAL;
            //   else if (inputChar == '#')
            //     return LESS;

              return (getLevel(inputChar) > getLevel(optrStackTop)) ? GREATER : LESS;
            }

            // Evaluate value while inputing operators
            void Calculate::evaluate(char ch) {
              char op;
              int num, result;

              if (!isOperator(ch)) {
                _opnd_stack.push(ascii_int(ch));
                return ;
              }

              switch (compareOpteratorLevel(ch, _optr_stack.top()))
                {
                case GREATER :
                  _optr_stack.push(ch);
                  break;

                case EQUAL :
                  _optr_stack.pop();
                  break;

                case LESS :
                  num = _opnd_stack.top();
                  _opnd_stack.pop();

                  result = _opnd_stack.top();
                  _opnd_stack.pop();

                  op = _optr_stack.top();
                  _optr_stack.pop();

                  result = calc(result, num, op);
                  _opnd_stack.push(result);
                  evaluate(ch);
                  break;
                }
            }

            // Evaluate user specified expression
            int Calculate::evaluteExpr(char *exp) {
              _optr_stack.push('#');
              for (char *p =exp; *p != '\0'; ++p )
                evaluate(*p);

              int result = _opnd_stack.top();
              _opnd_stack.pop();

              return result;
            }


            // 測試代碼 calc_test.cxx
            #include <iostream>
            #include "Calc.h"
            using namespace std;

            int main(void) {
              Calculate *calc = new Calculate();
              cout << "1+3*(4+7) = "
                   << calc->evaluteExpr("1+3*(4+7)#")
                   << endl;
              cout << "((1+2)) = "
                   << calc->evaluteExpr("((1+2))#")
                   << endl;
              cout << "3*8+9/7-5-9+(1-9)/4 = "
                   << calc->evaluteExpr("3*8+9/7-5-9+(1-9)/4#")
                   << endl;
              cout << "(6-7)*(5+9) = "
                   << calc->evaluteExpr("(6-7)*(5+9)#")
                   << endl;
              cout << "0*8+0/6-9+(7-1) = "
                   << calc->evaluteExpr("0*8+0/6-9+(7-1)#")
                   << endl;

              delete calc;
            }

            用 MinGW/G++ 3.4.5 編譯如下:
              g++  -o test.exe  Calc.cxx  Calc_test.cxx

            作為一個演示算法夠了, 但代碼還是有一些缺點:
               (1) 只能處理一位數的加、減、乘、除表達式計算(可帶括號)
               (2) 沒有任何錯誤處理,例如不能在表達式中有空格


            posted on 2008-01-02 10:01 Normandy 閱讀(5886) 評論(7)  編輯 收藏 引用 所屬分類: Programming

            評論

            # re: 用 C++ 實現的加、減、乘、除表達式計算[未登錄]  回復  更多評論   

            或者編譯里面的遞歸下降方法來分析表達式
            2008-01-02 12:27 | ngaut

            # re: 用 C++ 實現的加、減、乘、除表達式計算  回復  更多評論   

            利用動態數組,對掃描結果進行臨時存儲,那樣的話可以實現和計算器一樣的復雜表達式的計算

            # re: 用 C++ 實現的加、減、乘、除表達式計算  回復  更多評論   

            見數據結構里。先轉換到后序表達式再算
            2008-01-03 15:57 | Zeus2

            # re: 用 C++ 實現的加、減、乘、除表達式計算  回復  更多評論   

            解決問題的思路不錯!學習
            2008-01-07 11:13 | kyle

            # re: 用 C++ 實現的加、減、乘、除表達式計算  回復  更多評論   

            可以使用算符優先級,用棧記錄算符和操作數。也可以像編譯一樣先分詞再語法分析生成語法樹就可以直接算了
            2008-02-02 10:40 | 張磊

            # re: 用 C++ 實現的加、減、乘、除表達式計算  回復  更多評論   

            用什么堆棧啊,高手的話直接用遞歸
            2009-08-31 16:04 | jj

            # re: 用 C++ 實現的加、減、乘、除表達式計算  回復  更多評論   

            @jj
            不直到就不要亂說,能不用遞歸的都不要用!
            2009-09-18 11:19 | zigzag
            亚洲国产香蕉人人爽成AV片久久| 久久精品中文騷妇女内射| 国产精品成人无码久久久久久| 伊人久久综在合线亚洲2019| 欧美精品一区二区久久| 日本五月天婷久久网站| 国产精品九九九久久九九| 亚洲欧洲中文日韩久久AV乱码| 久久久久久久久无码精品亚洲日韩| 国产毛片久久久久久国产毛片| 99久久国产综合精品女同图片| 青青青国产成人久久111网站| 欧美久久久久久| 精品999久久久久久中文字幕| 波多野结衣久久一区二区 | 国产亚洲美女精品久久久| 欧美日韩精品久久久免费观看| 久久人人爽人人爽人人AV | 韩国无遮挡三级久久| 香港aa三级久久三级老师2021国产三级精品三级在 | 2021精品国产综合久久| 久久青青色综合| 久久免费视频一区| 97精品伊人久久久大香线蕉| 久久久亚洲欧洲日产国码aⅴ | 久久久久中文字幕| 久久国产色AV免费看| 无码日韩人妻精品久久蜜桃| 一本色道久久88综合日韩精品| 久久精品18| 欧美一级久久久久久久大片| 精品久久久久久无码免费| 国产 亚洲 欧美 另类 久久| A狠狠久久蜜臀婷色中文网| 久久99精品久久久久久动态图| 伊人久久综合无码成人网| 18禁黄久久久AAA片| 久久精品成人欧美大片| 中文字幕乱码人妻无码久久 | 国产精品成人久久久久久久| 国产精品激情综合久久|