题目:http://acm.hdu.edu.cn/showproblem.php?pid=3528
和POJ2314类似的思想,就是一个parser,画画状态转换关系就行了,不过需要注意的是:对单个case,遇到连续的两个'\n'之后,本case就不能再getchar了
#include <cstdio>
#include <cctype>
#include <string>
using namespace std;
struct Statement
{
virtual void Execute() = 0;
};
struct Write : Statement{
string literal;
void Execute(){
puts(literal.c_str());
}
};
struct IfSuite : Statement{
char condition;
Statement* ifClause;
Statement* elseClause;
IfSuite() : ifClause(NULL), elseClause(NULL){}
~IfSuite(){
delete ifClause; //ifClause always exists
delete elseClause; //delete NULL is ok
}
void Execute(){
if(condition == '0'){
if(elseClause) elseClause->Execute(); //else clause can be omitted
}
else{
ifClause->Execute(); //if clause can not be omitted
}
}
};
bool eoc = false; //flag of end of case input
Write* InputWrite()
{
Write* p = new Write;
int c;
//discard "
while((c = getchar()) != '"') ;
//literal is those chars before next "
while((c = getchar()) != '"') p->literal.push_back(c);
//discard )
while((c = getchar()) != ')') ;
return p;
}
//forward declaration
Statement* InputStatement();
IfSuite* InputIfSuite()
{
IfSuite* p = new IfSuite;
int c, x = 0;
//discard ( before condition expression
while((c = getchar()) != '(') ;
//we allow whitespaces between "(" and ")"
while(c = getchar(), isspace(c)) ;
p->condition = c;
//discard )
while((c = getchar()) != ')') ;
//if clause must exist
p->ifClause = InputStatement();
//else clause may not exist
//we need to take care of end of case here, which is two continuous '\n' of EOF
if(!eoc){
while(c != -1 && c != 'e' && !(x == '\n' && c == '\n')){
x = c;
c = getchar();
}
if(c == 'e'){//there is else clause for in if suite
getchar(); getchar(); getchar();
p->elseClause = InputStatement();
}
else eoc = true;
}
return p;
}
Statement* InputStatement()
{
int c;
while((c = getchar()) != -1 && isspace(c)) ;
if(c == -1){
eoc = true;
return NULL;
}
if(c == 'w') return InputWrite();
return InputIfSuite();
}
int main()
{
while(Statement* p = InputStatement()){
p->Execute();
delete p;
eoc = false;
}
return 0;
}