POJ 3972 BF (字符串模拟)

本文介绍了一种简单但有趣的编程语言BF的解析器实现过程。BF语言使用简单的指令集进行编程,挑战程序员的思维。文章详细解释了BF语言的语法,并提供了一个完整的BF语言解析器代码示例,包括如何处理各种指令、输入输出流等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://poj.org/problem?id=3972

BF
Time Limit: 5000MS Memory Limit: 65536K
Total Submissions: 241 Accepted: 53

Description

BF is a language that was designed to challenge and amuse programmers. BF uses a simple machine model consisting, besides the program, of: 

  • An array of 30,000 byte cells – byte value ranges from 0 to 255 - initialized to zeroes.
  • A movable pointer into a circular array (initialized to point to location 0)
  • Two streams of bytes for input and output (most often connected to a keyboard and a monitor respectively, and using the ASCII character encoding).

In this problem you are asked to implement a BF interpreter, your program should read a BF program and an input stream and should print the output stream. 

BF syntax is easy, only the following commands are available: 

CharacterSpelled asMeaning
>Greater thanIncrement the pointer (to point to the next cell to the right).
<Less thanDecrement the pointer (to point to the next cell to the left).
+Plus signIncrement (increase by one) the byte at the pointer.
-Minus signDecrement (decrease by one) the byte at the pointer.
.Dot (period)Puts the value of the byte at the pointer into the output stream.
,CommaAccept one byte of input - from the input stream - storing its value in the byte at the pointer.
[Left square bracketJump forward to the command after the corresponding ‘]’ if the byte at the pointer is zero.
]Right square bracketJump back to the command after the corresponding ‘[‘ if the byte at the pointer is nonzero.


The given BF programs will be syntactically valid also the ‘>’ and ‘<’ operators will never lead to a value outside range [0-30000].

Input

Input starts with the number of test cases on a line by itself. Then a number of test cases; each test case is formatted as follows. 

  1. A BF program (possibly with extra letters and/or white space characters embedded anywhere in the text).
  2. A white space and a dollar sign – ‘$’ – indicating end of BF program.
  3. A space, the input stream, another space and a dollar sign terminator indicating the end of the input stream.
  4. A new line.

A test case may span on multiple lines and each two consecutive test cases are separated by a blank line. 

The  embedded text could be any characters except the dollar sign terminator, you should ONLY process the 8 commands and detect the end of program/input by the dollar signs, discard any other characters when processing. In the sample input only the relevant input is underlined, however in the real test cases there will be no signs of input termination except for the dollar signs.

Output

Output should be “Case “ then test case number (starting with 1) , a colon, a space followed by the contents of the BF program output stream and a new line after each test case.

Sample Input

3
,>,>,>,.<.<.<. $ abcde $

This is a sample BF program ,>++++++[<-------->-],[<+>-]<. That
Prints the summation of 2 numbers $ 23 $

,>,> ++++[<++++++++>-]<. >++++[<<++++++++>>-]<<. Adds to
every cell 8*4=32 and prints 'em in reverse order $ AB $

Sample Output

Case 1: dcba
Case 2: 5
Case 3: ba

Source



给出BF程式的命令(只含有> < + - , . [ ])即输入流($  $之间的)根据命令操作数组,输出输出流。

其他字符(样例中无下划线的)为注释,直接忽略

只要看懂这8个命令的含义就能切掉的水题

>数组光标向后移1位;

<数组光标向前移1位;

+数组当前光标所指位置ascll码+1;

-数组当前光标所指位置ascll码-1;

.输出当前光标所指字符至输出流;

,从输入流读入一个字符到光标位置;

[数组当前光标所指位置ascll码为0时,命令跳转到与其对应的]的后一位

]数组当前光标所指位置ascll码不为0时,命令跳转到与其对应的[的后一位

注意:数组位置从0开始,且是一个长度为30000的循环数组,[ ]要找到配对位置(用栈处理)


#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <stack>
using namespace std;

char stdcmd[]={"><+-,.[]\0"};

string cmd,in;
char out[30001];
int nex[30001];
char c;
int pc,pi,po;

stack<int> st;

int main()
{
 //   freopen("in.txt","r",stdin);

    int tt;

    scanf("%d",&tt);getchar();

    for (int t=1;t<=tt;t++)
    {
        bool f=true;

        cmd=in="";
        memset(out,0,sizeof(out));
        memset(nex,0,sizeof(nex));

        while (f)
        {
            c=getchar();
            if (c=='$') break;
            if (strchr(stdcmd,c)!=NULL)
                cmd+=c;
        }
        getchar();

        while (f)
        {
            c=getchar();
            if (c=='$') break;
            in+=c;
        }

        int last;

        while (!st.empty()) st.pop();

        for (int i=0;i<cmd.size();i++)
        {
            if (cmd[i]=='[')    st.push(i);
            if (cmd[i]==']')    {nex[i]=st.top();st.pop();}
        }

        while (!st.empty()) st.pop();

        for (int i=cmd.size()-1;i>=0;i--)
        {
            if (cmd[i]==']')    st.push(i);
            if (cmd[i]=='[')    {nex[i]=st.top();st.pop();}
        }
/*
        for (int i=0;i<cmd.size();i++)
        {
            printf("%d ",nex[i]);
        }
        puts("");
*/
        pc=0;
        pi=0;
        po=0;

        printf("Case %d: ",t);

      //  puts(cmd.c_str());
       // puts(in.c_str());

        while (pc!=cmd.size())
        {
            if (po==30000)  po=0;
            if (po==-1) po=29999;
            //printf("pc=%d\n",pc);
            //system("pause");

            if (cmd[pc]=='<')
            {
                po--;
                pc++;
                continue;
            }
            if (cmd[pc]=='>')
            {
                po++;
                pc++;
                continue;
            }
            if (cmd[pc]=='+')
            {
                out[po]++;
                pc++;
                continue;
            }
            if (cmd[pc]=='-')
            {
                out[po]--;
                pc++;
                continue;
            }
            if (cmd[pc]=='.')
            {
                putchar(out[po]);
                //printf("out[po]=%d\n",out[po]);
                pc++;
                continue;
            }
            if (cmd[pc]==',')
            {
                out[po]=in[pi++];
                pc++;
                continue;
            }
            if (cmd[pc]=='[')
            {
                if (out[po]=='\0')
                    pc=nex[pc];
                pc++;
                continue;
            }
            if (cmd[pc]==']')
            {
                if (out[po]!='\0')
                    pc=nex[pc];
                pc++;
                continue;
            }
        }

        puts("");

    }

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值