C++ 实现 算数表达式求值

来源:互联网 发布:mac svn客户端使用教程 编辑:程序博客网 时间:2024/06/05 04:09

好不容易抽出点时间来复习一下数据结构和算法。

看到堆栈部分。有2道题目,第一道是计算C系列括号匹配校验。第二道是计算算数表达式。

第一道题是思路是

跳过 ' ""字符串,/* // 注释以后。

如果发现{, [, ( 那么入栈,发现 },],) 以后出栈,对比是否匹配。

文件检查完以后,堆栈内为空,说明匹配成功。

(ps一句,很多代码是抄的)


第二道题思路

首先把中缀式转换为后缀式。

转换过程

1)若读入的是操作数,入到输出栈

2)读入的是闭括号,把操作栈中的运算符依次出栈,推入输出栈,一直遇到对应开括号为止,把开括号出栈

3)读入的开括号,进运算符栈

4)读入的是运算符,如果运算符栈优先级高,堆栈运算符出栈,出栈操作一直要进行到栈顶运算符优先级低为止,然后把新的运算符入栈

5)在读入操作符结束扣,把运算符栈中所有剩余运算符依次出栈,放入输出栈

6)计算输出堆表达式的


直接发代码.

先发堆栈的。

#ifndef __ListDemo__List__#define __ListDemo__List__#include <iostream>template <typename T>class ListNode{public:    T            element;    ListNode<T>  *next;public:    ListNode(T te, ListNode<T> *L):element(te), next(L){}    ListNode(T te):element(te), next(NULL){}};template <typename T>class Stack {private:    ListNode<T>      *head;public:    const int isEmpty() const;        void    push(T x);    T       pop();    T       top();};template <typename T>const int Stack<T>::isEmpty() const{    return head == NULL;}template <typename T>void Stack<T>::push(T x){    if (head == NULL)    {        head = new ListNode<T>(x);    }    else    {        ListNode<T> *p = new ListNode<T>(x, head);                head = p;    }}template <typename T>T Stack<T>::pop(){    if (head == NULL)    {//        return NULL;    }    ListNode<T> *p = head->next;    T x = head->element;    delete head;    head = p;        return x;}template <typename T>T Stack<T>::top(){    if (head == NULL)    {        //        return NULL;    }    return head->element;}#endif /* defined(__ListDemo__List__) */

第一道题:

#ifndef ListDemo_CheckFlag_h#define ListDemo_CheckFlag_h#include <iostream>#include "List.h"struct Symbol {    char    Token;    int     Theline;};class CheckFlag{private:    enum CommonentType { SlashSlash, SlashStar };   // // or /*    istream &       InputStream;    char            Ch;    int             CurrentLine;    Stack<Symbol>   PendingTokens;                  //没有处理的开括号    int             Errors;    private:    int NextChar();                                 //下1个字符    void PutBackChar();                             //把当前字符放回输入流    void SkipComment(CommonentType Start);          //跳过 // /*    void SkipQuote(char QuoteType);                 //跳过 '' 和 ""    char GetNextSymbol();                           //获得下1个括号    void CheckMatch(const Symbol & OpSym, const Symbol & ClSym);        //查开闭括号是否匹配    public:    CheckFlag(istream & Input) : Errors(0), CurrentLine(1), InputStream(Input){}    ~CheckFlag() {}    int CheckBalance();                             //检查括号是否匹配};int CheckFlag::NextChar(){    if (!InputStream.get(Ch))    {        return 0;    }    if (Ch == '\n')    {        CurrentLine++;    }    return 1;}void CheckFlag::PutBackChar(){    InputStream.putback(Ch);    if (Ch == '\n')    {        CurrentLine--;    }}void CheckFlag::SkipComment(CheckFlag::CommonentType Start){    if (Start == SlashSlash)    //处理 //    {        while (NextChar() && Ch != '\n')        {}        return;    }    int State = 0;              //处理 /*    while (NextChar())    {        if (State && Ch == '/')        {            return;        }        State = Ch == '*';    }    Errors ++;    std::cout << "Comment not is unterminated!" << std::endl;}void CheckFlag::SkipQuote(char QuoteType){    while (NextChar())    {        if (Ch == QuoteType)        {            return;        }        else if (Ch == '\n')            //搜索1行结束,没有找到引号        {            Errors++;            std::cout << "Missing closed quote at line" << CurrentLine << std::endl;        }        else if (Ch == '\\')        {            NextChar();                 //跳过\转义        }    }}char CheckFlag::GetNextSymbol(){    while (NextChar())    {        if (Ch == '/')        {            if (NextChar())            {                if (Ch == '*')                {                    SkipComment(SlashStar);                }                else if (Ch == '/')                {                    SkipComment(SlashSlash);                }            }        }        else if (Ch == '\'' || Ch == '"')        {            SkipQuote(Ch);        }        else if (Ch == '{' || Ch == '(' || Ch == '[' ||                 Ch == '}' || Ch == ')' || Ch == ']')        {            return Ch;        }    }    return 0;}int CheckFlag::CheckBalance(){    char LastChar;    Symbol LastSymbol, Match;    Errors = 0, CurrentLine = 1;        while ((LastChar = GetNextSymbol()))        //得到当前开闭括号    {        LastSymbol.Token = LastChar;        LastSymbol.Theline = CurrentLine;       //当前括号所在行号        switch (LastChar) {            case '(':            case '{':            case '[':                PendingTokens.push(LastSymbol);                break;                        case ')':            case '}':            case ']':                if (PendingTokens.isEmpty()) {                    Errors++;                    std::cout << "Extraneous" << LastChar << "at line" << CurrentLine << endl;                }                else                {                    Match = PendingTokens.pop();                    CheckMatch(Match, LastSymbol);                }                break;                            default:                break;        }    }        //堆栈还有数据    while (! PendingTokens.isEmpty()) {        Errors++;        Match = PendingTokens.pop();        std::cout << "Un matched" << Match.Token << "at line" << Match.Theline << std::endl;    }        return Errors;}void CheckFlag::CheckMatch(const Symbol &OpSym, const Symbol &ClSym){    if ((OpSym.Token == '(' && ClSym.Token == ')') ||        (OpSym.Token == '{' && ClSym.Token == '}') ||        (OpSym.Token == '[' && ClSym.Token == ']')        )    {        std::cout        << "Found open flag: " << OpSym.Token << " on line " << OpSym.Theline        << " close flag: " << ClSym.Token << "on line " << ClSym.Theline         << std::endl;    }    else    {        std::cout << "does not match" << ClSym.Token << "at line" << OpSym.Theline << std::endl;        Errors++;    }}#endif

第二道题

#ifndef ListDemo_Evaluator_h#define ListDemo_Evaluator_h#include "List.h"#include <string>class EvalValue{public:    int         value;    int         opType;public:    EvalValue(int v, int o):value(v),opType(o){}};class Evaluator{private:    Stack<EvalValue>      *OpStack;               //操作符    Stack<EvalValue>      *PostFixStack;          //数值        enum {        UNKNOW = 100,       //  未知        OPAREN,             //  (        CPAREN,             //  )        EXP,                //  ^        MULT,               //  *        DIV,                //  /        PLUS,               //  +        MINUS,              //  -    };    string          *sEval;    private:    int GetCharOp(char Ch);    bool IsDigit(char Ch);    int Digit(char Ch);    void CheckOp(int op);        void openFlagEval();                        //括号处理    void orderOpEval(int op);                   //优先级处理    bool checkOpOrder(int TopOp, int op);       //比较优先级    void EvalResult();                          //计算结果    string getOpString(int op);                 //得到运算符的字符串    int CacluateWithValue(int op, int v1, int v2);      //计算public:    Evaluator(const char *strEval);    virtual ~Evaluator()    { delete sEval; delete OpStack; delete PostFixStack; }    public:    void Convert();    string Original();    string Converted();    int Caculator();};Evaluator::Evaluator(const char *strEval){    sEval = new string(strEval);    OpStack = new Stack<EvalValue>;    PostFixStack = new Stack<EvalValue>;}void Evaluator::Convert(){    int value = 0;    for (int i = 0; i < sEval->size(); i++)    {        char Ch = (*sEval)[i];        if (this->IsDigit(Ch))        {            value = value * 10 + this->Digit(Ch);                    }        else        {            if (value != 0)            {                PostFixStack->push(EvalValue(value, 0));            }            if (Ch == ' ')            {                value = 0;                continue;            }            int type = this->GetCharOp(Ch);            if ( type != UNKNOW)            {                this->CheckOp(type);            }            else            {                cout << "error" << endl;                return;            }            value = 0;        }    }    if (value != 0)    {        PostFixStack->push(EvalValue(value, 0));    }    this->EvalResult();}string Evaluator::Original(){    return *sEval;}string Evaluator::Converted(){    Stack<EvalValue> *tmp = new Stack<EvalValue>();    while (! PostFixStack->isEmpty() )    {        tmp->push(PostFixStack->pop()) ;    }    while (! tmp->isEmpty() )    {        EvalValue eva = tmp->pop();        if (eva.opType != 0)        {            cout << this->getOpString(eva.opType) << " ";        }        else        {            cout << eva.value << " ";        }    }    delete tmp;    cout << endl;    return string("");}int Evaluator::Caculator(){    Stack<EvalValue> *reveral = new Stack<EvalValue>();    while (! PostFixStack->isEmpty() )    {        reveral->push(PostFixStack->pop()) ;    }    Stack<EvalValue> *tmp = new Stack<EvalValue>();        while (! reveral->isEmpty() )    {        EvalValue eva = reveral->pop();        if (eva.opType != 0)        {//            cout << this->getOpString(eva.opType) << " ";            int value1 = tmp->pop().value;            int value2 = tmp->pop().value;            int Vtmp = this->CacluateWithValue(eva.opType, value1, value2);            tmp->push(EvalValue(Vtmp, 0));        }        else        {//            cout << eva.value << " ";            tmp->push(eva);        }    }    EvalValue eva = tmp->pop();    delete tmp;    delete reveral;        return eva.value;}int Evaluator::GetCharOp(char Ch){    switch (Ch) {        case '(':   return OPAREN;        case ')':   return CPAREN;        case '^':   return EXP;        case '*':   return MULT;        case '/':   return DIV;        case '+':   return PLUS;        case '-':   return MINUS;        default:    return UNKNOW;    }}bool Evaluator::IsDigit(char Ch){    if (Ch >= '0' && Ch <= '9')    {        return true;    }    return false;}int Evaluator::Digit(char Ch){    return Ch - '0';}void Evaluator::CheckOp(int op){    switch (op) {        case OPAREN:            OpStack->push(EvalValue(0, op));            break;        case CPAREN:            //出栈计算            this->openFlagEval();            break;        case EXP:        case MULT:        case DIV:        case PLUS:        case MINUS:            //优先级            this->orderOpEval(op);            break;                    default:            break;    }}void Evaluator::openFlagEval(){    EvalValue ev = OpStack->pop();    while (ev.opType != OPAREN)    {        PostFixStack->push(ev);        ev = OpStack->pop();    }}void Evaluator::orderOpEval(int op){    if (!OpStack->isEmpty())    {        EvalValue ev = OpStack->top();        //栈顶优先级高        while (this->checkOpOrder(ev.opType, op))        {            PostFixStack->push(OpStack->pop());        }            }    OpStack->push(EvalValue(0, op));}bool Evaluator::checkOpOrder(int TopOp, int op){    if (TopOp < op)    {        if (TopOp == EXP ||                     // ^悠闲级高            (TopOp == MULT && op < DIV))        // * / 大于 + - 优先级        {            return true;        }    }    return false;}void Evaluator::EvalResult(){    while (!OpStack->isEmpty())    {        PostFixStack->push(OpStack->pop());    }}string Evaluator::getOpString(int op){    switch (op) {        case OPAREN:    return "(";        case CPAREN:    return ")";        case EXP:       return "^";        case MULT:      return "*";        case DIV:       return "/";        case PLUS:      return "+";        case MINUS:     return "-";        default:            break;    }    return "[error]";}#include <math.h>int Evaluator::CacluateWithValue(int op, int v1, int v2){    switch (op) {        case EXP:   return pow(v2, v1);        case MULT:  return v2 * v1;        case DIV:   return v2 / v1;        case PLUS:  return v2 + v1;        case MINUS: return v2 - v1;                    default:            break;    }    return 0;}#endif



原创粉丝点击