茴字的确有四种写法- -
来源:互联网 发布:php new class 返回值 编辑:程序博客网 时间:2024/06/02 17:17
昨天做了一下POJ2106,很明显就是一道表达式求值的题:中序转化为后序,然后求值。三年前准备考研的时候不说闭着眼睛至少很快我也能写出来,但是这几年貌似待废了,昨天想了很久还看了书才想起来算法…真丢人。在校内发了这条状态,师兄回复说“表达式求值有四种写法,你都会么?”当时我过度紧张blabla了两句才发现是在茴香豆= =不过最后发现这道题还真的(至少)有四种写法
1 表达式求值,用栈
比较中规中矩的写法。贴个自己的。有bug但是不妨碍过- -
#include <iostream>#include <stack>#include <string>using namespace std;int getPrio(char a){switch (a) {case '|':return 1;break;case '&':return 2;break;case '!':return 3;break;default:return 0;break;}}int main (int argc, char * const argv[]) {string expr;int nExpr = 1;while (getline(cin, expr)) {string::iterator exprItr;string postfix;stack<char> operandStack;stack<char> operatorStack;for (exprItr = expr.begin(); exprItr != expr.end(); ++exprItr) {char tempChar = *exprItr;if (tempChar == 'V' || tempChar == 'F') {postfix.push_back(tempChar);}else if (tempChar == '(') {operatorStack.push(tempChar);}else if (tempChar == ')') {if (operatorStack.empty()) {break; //parenthesis don't match.}while (true) {char topOperator = operatorStack.top();operatorStack.pop();if (topOperator == '(')break;else {postfix.push_back(topOperator);}}}else if (tempChar == '&' || tempChar == '|') {while (!operatorStack.empty() && operatorStack.top() != '(' && getPrio(operatorStack.top()) >= getPrio(tempChar)) {postfix.push_back(operatorStack.top());operatorStack.pop();}operatorStack.push(tempChar);}else if (tempChar == '!') {while (!operatorStack.empty() && operatorStack.top() != '(' && getPrio(operatorStack.top()) > getPrio(tempChar)) {postfix.push_back(operatorStack.top());operatorStack.pop();}operatorStack.push(tempChar);}}while (!operatorStack.empty()) {postfix.push_back(operatorStack.top());operatorStack.pop();}//cout << postfix << endl;for (exprItr = postfix.begin(); exprItr != postfix.end(); ++exprItr) {char tempChar = *exprItr;if (tempChar == 'V' || tempChar == 'F') {operandStack.push(tempChar);}else if (tempChar == '&') {char rightOperand = operandStack.top();operandStack.pop();char leftOperand = operandStack.top();operandStack.pop();if (leftOperand == 'V' && rightOperand == 'V') {leftOperand = 'V';} else {leftOperand = 'F';}operandStack.push(leftOperand);}else if (tempChar == '|') {char rightOperand = operandStack.top();operandStack.pop();char leftOperand = operandStack.top();operandStack.pop();if (leftOperand == 'F' && rightOperand == 'F') {leftOperand = 'F';} else {leftOperand = 'V';}operandStack.push(leftOperand);}else if (tempChar == '!') {char operand = operandStack.top();operandStack.pop();if (operand == 'V')operand = 'F';else {operand = 'V';}operandStack.push(operand);}}cout << "Expression " << nExpr << ": " << operandStack.top() << endl;nExpr ++;} return 0;}
2 师弟用递归写了一个表达式求值
/*POJ 2106±í´ïʽÇóÖµ¡£×Ô¼ºÐ´ÁËÒ»¸öºÜʺµÄµÝ¹é½â·¨£¬ËٶȺÜÂý¡£ÓÃLL1ÎÄ·¨¿ÉÒÔÇáÈ¡*/#include <string>#include <iostream>using namespace std;bool calc(string s);string trim(string s){ int pos1 = 0; int pos2 = s.length() - 1; while (s[pos1] == ' ') pos1++; while (s[pos2] == ' ') pos2--; return s.substr(pos1, pos2 - pos1 + 1);}int findmatchedbrace(int start, string s){ int pos = start; while (s[pos] != '(' && s[pos] != ')') { pos++; } if (s[pos] == ')') return pos; pos = findmatchedbrace(pos + 1, s); return findmatchedbrace(pos + 1, s);}bool calcand(string s){ int pos = 0; int start = pos; string str = trim(s); string ands[100]; int cnt = 0; while (pos < str.length()) { if (str[pos] == '(') { pos = findmatchedbrace(pos + 1, str); } else if (str[pos] == '&') { ands[cnt++] = str.substr(start, pos - start); start = pos + 1; pos = start - 1; } pos++; } ands[cnt++] = str.substr(start, pos - start); if (cnt == 1) { if (str[0] == '!') return !calc(str.substr(1, str.length() - 1)); else if (str[0] == '(') { int match = findmatchedbrace(1, str); return calc(str.substr(1, match - 1)); } } for (int i = 0; i < cnt; i++) { if (!calc(ands[i])) return false; } return true;}bool calc(string s){ string str = trim(s); if (str.length() == 1) { return str == "V"; } int pos = 0; string ors[100]; int cnt = 0; int start = pos; while (pos < str.length()) { if (str[pos] == '(') { pos = findmatchedbrace(pos + 1, str); } else if (str[pos] == '|') { ors[cnt++] = str.substr(start, pos - start); start = pos + 1; pos = start - 1; } pos++; } ors[cnt++] = str.substr(start, pos - start); if (cnt == 1) { return calcand(str); } for (int i = 0; i < cnt; i++) { if (calc(ors[i])) return true; } return false;}int main(){ char str[1001]; int cnt = 0; while (cin.getline(str, 1001)) { cnt++; string s = str; if (calc(s)) cout << "Expression " << cnt << ": V" << endl; else cout << "Expression " << cnt << ": F" << endl; } return 0;}
3 后来F看了提到用树的思想,没有实现
4 最后来看一下神牛的方法:LL1文法——这尼玛才是编译原理活用到极致啊(swgr@poj)
#include<iostream>#include<string>using namespace std;string rep[14][2] = {" ","","!!","","(V)","V","(F)","F","!V","F","!F","V","V&V","V","V&F","F","F&V","F","F&F","F","V|V","V","V|F","V","F|V","V","F|F","F"};string s;int main(){int i,t,count=1;while(getline(cin,s)){while (1){for(i=0;i<14;i++)if((t=s.find(rep[i][0]))!=string::npos){s.erase(t,rep[i][0].length());s.insert(t,rep[i][1]);break;}if (i==14) break;}cout<<"Expression "<<count++<<": "<<s<<endl;}return 0;}
- 茴字的确有四种写法- -
- php之茴字写法
- “呵呵,的确
- 写法
- C++程序设计语言练习4.2 茴字的几种写法
- 的确,的确,要对老婆好一点
- gvim 6.3 的确不错.
- 工作风格的确定
- 分区魔术师的确好用
- python的确是个好工具
- JS的确认DIV
- 这里的确是专栏
- 重载函数的确定
- 抄的确是经典
- 敏捷无敌,的确无敌
- GFlags的确好用呀。
- 实现模式的确认
- 顺,的确很顺
- Linux 汇编语言开发指南 && 开发 Linux 命令行实用程序
- UIImagePickerController
- ECLIPSE DEBUG时怎样以十六进制的方式查看变量的值?
- Tair: 淘宝的key/value解决方案
- Google+ 内幕:搜索巨人的社交网络努力
- 茴字的确有四种写法- -
- .NET调PHP Web Service的典型例子
- Linux-2.6.39 在华恒2410 移植
- Cocoa中对日期和时间的处理 NSDate
- 东芝科学家向量子计算机迈进一大步
- 基于Ubuntu10.10 开发环境部署 2.6 内核
- 世界最小晶体管问世:仅由7个原子构成
- 两年的工作经历觉得需要学习的还很多啊
- 系统调用4