• <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 閱讀(5871) 評論(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无码久久久久不卡蜜桃| 精品久久久久久久久午夜福利| 久久精品成人免费网站| 久久综合九色欧美综合狠狠 | 久久国产精品视频| 久久久久亚洲AV成人网| 久久精品一本到99热免费| 久久精品国产亚洲综合色| 久久久久亚洲AV成人网人人网站| 久久人人爽人人爽人人片AV不 | 国产99精品久久| 亚洲精品美女久久久久99小说 | 国产91久久精品一区二区| 亚洲国产天堂久久综合| 久久久久亚洲AV无码麻豆| 久久精品国产一区二区三区不卡| 国产偷久久久精品专区| 99久久免费只有精品国产| 777午夜精品久久av蜜臀 | 国产精品99久久久精品无码| 成人资源影音先锋久久资源网| 久久国产精品一区| 国产精品久久久久9999高清| 18禁黄久久久AAA片| 久久国产免费| 精品久久久久久无码人妻蜜桃| 韩国免费A级毛片久久| 国产成人综合久久精品红| 久久国产午夜精品一区二区三区| 久久AV高清无码| 精品久久久久久国产潘金莲| 伊人久久大香线蕉av不卡| 精品国产日韩久久亚洲| 思思久久99热只有频精品66| 无码人妻少妇久久中文字幕| 国产精品热久久无码av| 很黄很污的网站久久mimi色| 久久99精品国产99久久6男男|