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
- C++ 实现 算数表达式求值
- 算数表达式求值C++实现
- 算数表达式求值(C语言)
- 算数表达式求值
- 算数表达式求值
- 算数表达式求值
- 算数表达式求值
- 算数表达式求值
- 简单算数表达式求值
- 中缀算数表达式求值
- QT算数表达式求值
- 算数表达式逻辑表达式求值
- c实现表达式求值
- C语言 算数表达式求值(顺序栈应用实例)
- 栈3-算数表达式求值
- Java字符串算数表达式求值
- 表达式求值:Objective-C实现
- 运用栈对算数表达式求值
- java的内存泄露
- poj 1837 0-1背包问题
- Android开发 之 多个Activity时的完美退出方法
- 剖析Hello World
- 【iOS 7】使用UIScreenEdgePanGestureRecognizer实现swipe to pop效果
- C++ 实现 算数表达式求值
- cocos2d-x节点(TransformUtils.h)API
- cocos2d-x节点(CCVertex.h)API
- cocos2d-x节点(ccUtils.h)API
- cocos2d-x节点(ccUTF8.h)API
- IDA 字符串解密脚本
- hdu 4771 Stealing Harry Potter's Precious
- UVa 10812 Beat the Spread! (陷阱)
- cocos2d-x节点(CCProfiling.h)API