数据结构之栈(四)
来源:互联网 发布:单反推荐 知乎 编辑:程序博客网 时间:2024/06/05 18:03
本文将继续扩展Stack在Arithmetical Expression的处理方面的应用,其中包括:“Postfix2Prefix”、“Postfix2Infix”和“Infix2Postfix”。
一、“Postfix2Prefix”
它是通过多次入栈和出栈来完成的。主要步骤是:遍历“postfix string”:
1)是算子先压栈;
2)是算符就先取出它需要的算子,调整顺序(保证算符在前,算子在后),并焊接在一个整体(string),再压栈。
bool IsOperator(char c){ if (c == '+' || c == '-' || c == '*' || c == '/' || c == '^') return true; else return false;}void Postfix2Prefix(string & postfix, string & prefix){ // convert the input postfix expression to prefix format StackAsLinkedList stack; for (unsigned int i = 0; i < postfix.length(); ++i) //process each char in the postfix string from left to right { string s{ postfix[i] }; if (std::isdigit(postfix[i])) stack.Push(*new String(s)); else if (IsOperator(postfix[i])) { String & arg2 = dynamic_cast<String&>(stack.Pop()); String & arg1 = dynamic_cast<String&>(stack.Pop()); stack.Push(*new String(s + string(arg1) + string(arg2))); delete &arg1; delete &arg2; } } String & arg = dynamic_cast<String&>(stack.Pop()); prefix = string(arg); delete & arg;}
二、“Postfix2Infix”
它的原理于上面的相似,只是在调整顺序的时候,保证“算符在算子中间,并添加圆括号”。
void Postfix2Infix(string & postfix, string & infix){ // convert the input postfix expression to infix format StackAsLinkedList stack; for (unsigned int i = 0; i < postfix.length(); ++i) //process each char in the postfix string from left to right { string s{ postfix[i] }; if (std::isdigit(postfix[i])) stack.Push(*new String(s)); else if (IsOperator(postfix[i])) { String & arg2 = dynamic_cast<String&>(stack.Pop()); String & arg1 = dynamic_cast<String&>(stack.Pop()); stack.Push(*new String(string("(") + string(arg1) + s + string(arg2) + string(")"))); delete &arg1; delete &arg2; } } String & arg = dynamic_cast<String&>(stack.Pop()); infix = string(arg); delete & arg;}
注:类似的原理,也可以处理“prefix expression”。
三、“Infix2Postfix”
它的原理要稍微复杂一些。需要比较运算符的优先级和考虑运算符的结合性以及圆括号。它也是遍历“infix string”:
1)遇到数字,直接append到“postfix string”;
2)遇到算符,与栈顶的算符比较优先级,如果栈顶算符优先级高,则将栈顶算符append到“postfix string”,反复进行比较,知道遇到圆括号,或者栈顶算符优先级更低为止,最后将新算符压栈(这样,栈内的算符优先级是从低到高顺序排序);
3)遇到左括号压栈,遇到右括号出栈。(对于括号是成对处理)
int GetOperatorWeight(char op){ int weight = -1; switch (op) { case '+': case '-': weight = 1; break; case '*': case '/': weight = 2; break; case '^': weight = 3; break; } return weight;}bool IsRightAssociative(char op){ if (op == '^') return true; else return false;}bool HasHigherPrecendence(char lOperator, char rOperator){ int op1Weight = GetOperatorWeight(lOperator); int op2Weight = GetOperatorWeight(rOperator); // If operators have equal precedence, return true if they are left associative. // return false, if right associative. // if operator is left-associative, left one should be given priority. if (op1Weight == op2Weight) { if (IsRightAssociative(lOperator)) return false; else return true; } return op1Weight > op2Weight ? true : false;}void Infix2Postfix(string & infix, string & postfix){ // convert the input infix expression to postfix format StackAsLinkedList stack; for (unsigned int i = 0; i < infix.length(); ++i) //process each char in the postfix string from left to right { string s{ infix[i] }; if (infix[i] == ' ' || infix[i] == ',') // If character is a delimitter, move on. continue; else if (std::isdigit(infix[i])) postfix += infix[i]; else if (IsOperator(infix[i])) // If character is operator { while (!stack.IsEmpty() && string(dynamic_cast<String&>(stack.Top())) != string("(") && HasHigherPrecendence(string(dynamic_cast<String&>(stack.Top()))[0], infix[i])) // operators in stack ordered by precedence { String & arg = dynamic_cast<String&>(stack.Pop()); postfix += string(arg); delete &arg; } stack.Push(*new String(string{ infix[i] })); } else if (infix[i] == '(') { stack.Push(*new String(string{ infix[i] })); } else if (infix[i] == ')') // a pair of parenthesis is a processing unit { while (string(dynamic_cast<String&>(stack.Top())) != string("(")) { String & arg = dynamic_cast<String&>(stack.Pop()); postfix += string(arg); delete &arg; } stack.Pop(); } } while (!stack.IsEmpty()) { String & arg = dynamic_cast<String&>(stack.Pop()); postfix += string(arg); delete &arg; }}
注:从该函数对圆括号的成对处理方法,可以扩展:在处理C++代码时,由于代码块是用花括号包裹,而花括号也是成对出现的,也可以采用栈进行缓存处理。或者,更简单的办法是“计算”。设定“int count = 0”;遇到左花括号则“++count”;遇到右花括号则“--count”;
0 0
- 数据结构之栈(四)
- 数据结构之栈和队列(四)
- 四.学习数据结构之栈
- 数据结构之队列(四)
- 数据结构(四):栈
- SDUT2134数据结构实验之栈四:括号匹配(栈)
- 数据结构实验之栈四:括号匹配(java实现)
- 数据结构实验之栈四:括号匹配
- 数据结构实验之栈四:括号匹配
- 数据结构实验之栈四:括号匹配
- 数据结构实验之栈四:括号匹配
- 数据结构实验之栈四:括号匹配
- 数据结构实验之栈四:括号匹配
- 数据结构实验之栈四:括号匹配
- 数据结构实验之栈四:括号匹配
- 数据结构实验之栈四:括号匹配
- 数据结构实验之栈四:括号匹配
- 数据结构实验之栈四:括号匹配
- Java中==与equals方法的区别
- Android层测试摄像头实际输出帧率大小
- Codeforces Experimental Educational Round: VolBIT Formulas Blitz D. Hexagons!
- OOA/OOD/OOP的区别
- android中finish()与system.exit(0)的区别?
- 数据结构之栈(四)
- 设计模式 命令模式 之 管理智能家电
- 图像模式
- SpringMVC中url-parden配置的问题和SpringMVC中js、css不生效问题
- vs2013窗口布局恢复
- Inno Setup中控件的创建及事件响应
- 是人才就不要等老板来安排你的工作 !
- 详解a href=#与 a href=javascript:void(0) 的区别
- 此证书的签发者无效Missing iOS Distribution signing identity问题解决