POJ3201 Little Quilt 构建语法树 暴力模拟

Language:Default
Little Quilt
Time Limit: 1000MSMemory Limit: 65536K
Total Submissions: 814Accepted: 260

Description

Little Quilt is a small language introduced by Ravi Sethi in his book ‘Programming Languages’. Here, a restricted version of Little Quilt is presented.

The language is defined by the following BNF grammar:

<QUILT> ::= A | B | turn(<QUILT>) | sew(<QUILT>,<QUILT>)

A and B represent the two primitive quilts. Each primitive quilt corresponds to a matricial arrangement of 2 × 2 characters. turn() and sew() are operations over quilts.

The instruction turn(x) turns the quilt x 90 degrees clockwise. The following table illustrates the primitive quilts as well as examples of the effect of the turn() operation:

A//
/+
turn(A)\\
+\
turn(turn(A))+/
//
turn(turn(turn(A)))\+
\\
B--
--
turn(B)||
||

Accordingly, the instruction sew(x,y) sews quilt x to the left of quilt y. Both x and y must have the same height, otherwise an error will be generated. The following figure represents the result of sew(A,turn(B)):

//||
/+||

while the sew(turn(sew(B,turn(B))),A) generates an error message.

Your job is to build an interpreter of the Little Quilt language.

Input

The input file will be a text file containing different Little Quilt expressions, each one ended by a semicolon character (;). Space and new line characters must be ignored; this means that an expression may span several lines.

Output

The output file contains the quilts produced as a result of interpreting the input expressions.

Each quilt must be preceded by a line, left aligned, with the format

Quilt i:

where i is the quilt number, starting at 1. If the expression interpretation generates and error, the word

error

must be printed.

Sample Input

sew(turn(sew(B,turn(B))),
       turn(sew(turn(B),B)))   ;

sew(turn(sew(B,turn(B))),A);
sew(turn(sew(A,turn(A))),
turn(turn(

turn(sew(A,turn(A))))))

;

Sample Output

Quilt 1:
||–
||–
–||
–||
Quilt 2:
error
Quilt 3:
\//
+/+
+/+
//\

Source

题意 :
给出一种简单语言 有两种操作语句(旋转,链接)和两个基本单元。
要求将给出的该语言的语句翻译成对应的符号矩阵。
思路:
看一眼基本就能确定是锻炼码力的暴力模拟题了。
根据给出的语句将之翻译成语法树,然后再计算就可以了。 因为只有4种符号,其实写起来还是很简单的。
我是用vector把所有符号存起来,旋转的话就是把vector里的所有符号的坐标调换一下就可以了,链接的话就是直接把一个vector里的元素把横坐标处理一下后放到另一个vector里。
其他的没什么好讲的。

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cstdio>
using namespace std;
string str;
vector<string> OPV;
char the_ch[10]={'/','\\','+','+','-','|'};
class POINT{
public:
    int x,y,ch;
    POINT(int x,int y,char ch):x(x),y(y),ch(ch){}
    bool operator < (const POINT &b)const{
        if(x==b.x){
            return y<b.y;
        }
        return x>b.x;
    }
};
class QUITL{
public:
    int lson,rson,is_end;
    vector<POINT>V;
    int H,W;
    void roll(){
        swap(H,W);
        for(int i=0;i<V.size();i++){
            //cout<<"("<<V[i].x<<","<<V[i].y<<")->";
            swap(V[i].x,V[i].y);
            V[i].x=H-V[i].x-1;
            //cout<<"("<<V[i].x<<","<<V[i].y<<")\n";
            //cout<<V[i].ch<<endl;
            V[i].ch^=1;
            //cout<<V[i].ch<<endl;
        }
    }
    bool my_merge(QUITL &b){
        if(b.H!=H){
            return 0;
        }
        for(int i=0;i<b.V.size();i++){
            V.push_back(POINT(b.V[i].x,b.V[i].y+W,b.V[i].ch));
        }
        W+=b.W;
        return 1;
    }
    void show(){
        sort(V.begin(),V.end());
        int num=0;
        for(int i=0;i<V.size();i++){
             cout<<the_ch[V[i].ch];
             num++;
             if(num==W){
                num=0;
                puts("");
             }
        }
    }
};
QUITL A,B;
QUITL quitl[100000];
int tot;
void init(){
    tot = 0;
    A.H=A.W=2;
    B.H=B.W=2;
    A.is_end=B.is_end=1;
    A.V.push_back(POINT(0,0,0));
    A.V.push_back(POINT(0,1,2));
    A.V.push_back(POINT(1,1,0));
    A.V.push_back(POINT(1,0,0));
    B.V.push_back(POINT(0,0,4));
    B.V.push_back(POINT(1,0,4));
    B.V.push_back(POINT(1,1,4));
    B.V.push_back(POINT(0,1,4));
    string cnt;
    string op;
    while(cin>>str){
        cnt+=str;
    }
    int len = cnt.size();
    for(int i=0;i<len;i++){
        if(cnt[i]!=' '){
            op+=cnt[i];
        }
    }
    len = op.size();
    cnt.clear();
    for(int i=0;i<len;i++){
        if(op[i]=='s'){
            cnt+='S';
            i+=2;
        }else if(op[i]=='t'){
            cnt+='T';
            i+=3;
        }else if(op[i]=='A' ||op[i]=='B' ){
            cnt+=op[i];
        }
        if(op[i]==';'){
            OPV.push_back(cnt);
            cnt.clear();
        }
    }
}
int build(string &s,int &index,int now){
    int ans=1;
    if(s[index]=='A'){
        quitl[now]=A;
    }
    if(s[index]=='B'){
        quitl[now]=B;
    }
    if(s[index]=='T'){
        index++;
        int lson = index;
        tot++;
        ans=build(s,index,tot);
        quitl[lson].roll();
        quitl[now]=quitl[lson];
    }
    if(s[index]=='S'){
        index++;
        int lson = index;
        tot++;
        ans=build(s,index,tot);
        quitl[now]=quitl[lson];
        index++;
        int rson = index;
        tot++;
        ans=(ans&&build(s,index,tot));
        ans=(ans&&quitl[now].my_merge(quitl[rson]));
    }
    //quitl[now].show();
    return ans;
}
int main(){
    //freopen("in.txt","r",stdin);
    init();
    for(int i=0;i<OPV.size();i++){
        //cout<<OPV[i]<<endl;
        printf("Quilt %d:\n",i+1);
        tot=0;
        int index = 0;
        if(build(OPV[i],index,0)){
            //quitl[0].roll();
            quitl[0].show();
        }else{
            puts("error");
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值