首页 > ACM题库 > HDU-杭电 > HDU 4594-Script Z-模拟-[解题报告]HOJ
2015
09-17

HDU 4594-Script Z-模拟-[解题报告]HOJ

Script Z

问题描述 :

Recently, Programmer Zero have made a new script programming language, named Script Z. He is so proud of his new language, that he wrote many programs in Script Z. Unfortunately, he found his script works strangely, and he had no idea what happened. So he wants you to write a Script Z Interpreter for him.
Here are some information about Script Z:
1. Variable: All variable names start with symbol $, and the name of the variable should only contains letters (upper case and lower case), numbers and underlines (_). The first character of the number can be any legal character for the variable. For example, $a $c $t $0 $2 $_ are all legal variable names, while $0-a, $0%b are illegal ones. Variables can be assigned many times during the processing of the script. The length of variable name is no larger than 32. (Does not include the first $ symbol, so the max length of variable name will be 33 with symbol $).
2. Constant: All constant names must start with letters (upper case and lower case), and should only contains letters (upper case or lower case), numbers and underlines (_). For example, A B A10 B_123 are legal constant names, while 5A 4_b are illegal ones. Constants can be assigned at most once. The length of constant name is no larger than 32.
3. White spaces: Spaces (‘ ‘, ord(‘ ‘) == 32) and tabs (‘\t’, ord(‘\t’) == 9).
4. Lines: All lines are terminated with character LF(‘\n’, ord(‘\n’) == 10). Each line should be a statement or a blank line.
5. Statement: There will be exactly one statement in one line (except blank lines). The white spaces at the beginning and the end of the statement should be ignored.
6. Blank lines: One line that contains only white spaces or no character.
7. Data Types:
Integer: All integer contains only numbers ([0-9]). The length of integer is not larger than 100.
String: All string values are quoted with double quotes ("), and there won’t be any other double quotes in the string value. All characters in the string are printable[ We call a character printable, if and only if the ASCII code of the character is not smaller than 32 and is not larger than 127.]. The length of string (without double quotes) is not larger than 100. (The length is not larger than 102 if with double quotes.)
There are 5 kinds of statement in Script Z:
1. Assignment:
$Variable = Value
Constant = Value
Notice: there may be none or any number of white spaces before and after the equal sign (=).
The value can be either an integer or a string, and won’t be a reference of variable or constant.
The following assignment are legal:
$a = 1
$b = 2
$b = 3
$_ = "a"
$ok = "true"
$long = 123456789012345678901234567890
CONST = 1
CONST_STRING = "sample"
EMPTY = ""
And these are illegal:
$a = $b
CONST_STRING = a
BOOLEAN = false
FLOAT = 1.5
EMPTY =
2. Output:
Print $Variable
Print Constant
There are at least one white space between Print and variable or constant. For each output statement, your program should print the value of the variable or the constant. No double quotes are needed if the value is string. If the variable is undefined, you should print NULL, and if the constant is undefined, you should print the name of the constant. And also remember to take a look of error reporting part.
3. Dump:
Dump $Variable
Dump Constant
There are at least one white space between Dump and variable or constant. For each dump statement, your program should print the type and the value of the variable or the constant. Double quotes are needed if the value is string. If the variable is undefined, you should print NULL, and if the constant is undefined, you should regard the constant name as a string to be the value of the constant. And also remember to take a look of error reporting part. Use the format in sample output.
4. Error reporting:
Errmsg ON|OFF
There are at least one white space between Errmsg and ON or OFF. Errmsg ON turns on the error reporting while Errmsg OFF turns off. Error reporting is turned on if not specified. If error reporting is turned on, after each statement, you should:
(1) You should print one line if there are undefined variable in Print or Dump statement:
NOTICE: Undefined Variable ${var_name}.
You should replace ${var_name} with the name of variable.
(2) You should print one line if there are undefined constant in Print or Dump statement:
NOTICE: Undefined Constant {const_name}.
You should replace {const_name} with the name of constant.
(3) You should print one line if an assignment are trying to assign an assigned constant:
WARNING: Constant {const_name} Already Defined!
You should replace {const_name} with the name of constant. And you should ignore this assign statement even if the error reporting is turned off (The value of the constant should not be changed).
5. Terminate:
Panic
Your program should print one line and exit after this statement:
Script was KILLED.
You should ignore all statements after the terminate statement.

输入:

Input contains multiple test cases. The first line of the input contains exactly one integer T, which means the number of test cases. (T <= 10)
For each test case, the first line contains exactly one integer N, which means the lines of the script. (N <= 100000)
The next N lines, contains the statement of the script. Each line is no longer than 256 characters.
You are guaranteed that all statement, variable name, constant name are legal.

输出:

Input contains multiple test cases. The first line of the input contains exactly one integer T, which means the number of test cases. (T <= 10)
For each test case, the first line contains exactly one integer N, which means the lines of the script. (N <= 100000)
The next N lines, contains the statement of the script. Each line is no longer than 256 characters.
You are guaranteed that all statement, variable name, constant name are legal.

样例输入:

2
13
Errmsg ON
$a = 1
$b = 2
$c = 3
Print $a
Print $d
Dump $c
Errmsg OFF
Print $_
Print OK
Panic
Errmsg ON
Print A
13
Errmsg ON
$A = 3
$B = 5
Print $a
Print $B
A = 5
A = 10
Print A
Errmsg OFF
B = ""
B = "A"
Dump B
Dump C

样例输出:

1
NULL
NOTICE: Undefined Variable $d.
integer: 3
NULL
OK
Script was KILLED.

NULL
Notice: Undefined Variable $a.
5
WARNING: Constant A Already Defined!
5
string: ""
string: "C"
Hint
The problem itself is easy of course. But some of the test cases of this problem are strange and annoying. Be careful!

题意:大模拟,说下坑吧。

1. 用HashMap/自写Hash的话就自求多福吧,有专门卡Hash的数据。有队伍的代码TLE,不知道是不是这个原因。
2. Print, Dump, Errmsg, Panic是可以作为常量名的,所以应该先判断是不是赋值式,有很多队伍因为这个而WA掉了。
3. 在双引号中虽不会出现双引号,但是会出现空格。有一部分程序因为空格问题WA掉。
4. Errmsg默认是ON, 样例中故意在两个TestCase中都显式写明了Errmsg ON, 没有特判会WA。
5. 由于很多Printable的字符是特殊字符,似乎有队伍因为这个原因WA了, 原因不明。
6. 千万不要用cin/cout进行IO, java一定要套上BufferedReader, 不然40M的数据在读入阶段就会TLE。
7. 引号里面的字符串可能有等号! 用java的同学在split中一定要注意指明最大划分段数: 

String parts[] = Statement.split("=", 2); 
否则是必然会WA掉的

AC代码如下:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<map>
#include<iostream>
#include<string>
using namespace std;
typedef long long ll;
int T,t,n,m;
map<string,string> match[4];
char str[1010],str2[1010],s1[1010],s2[1010];
int type1,type2,Err,Over;
void init()
{
    int i,j,k;
    for(i=0;i<=3;i++)
       match[i].clear();
    Err=1;
    Over=0;
}
bool Has_Equal()
{
    int i,j,k,len=strlen(str);
    bool flag=0,flag2=0;
    for(i=0;i<len;i++)
    {
        if(str[i]==34)
          flag2=1;
        if(str[i]=='=' && flag2==0)
        {
            flag=true;
            str[i]=' ';
        }
        if(str[i]==9)
          str[i]=32;
    }
    return flag;
}
bool kong()
{
    int i,j,k,len=strlen(str);
    bool flag=0;
    for(i=0;i<len;i++)
       if(!(str[i]==' ' || str[i]==9))
         return false;
    return true;
}
void solve()
{
    int i,j,k,len=strlen(str);
    m=0;
    for(i=0;i<len;i++)
       if(str[i]==34)
         break;
    m=i;
    for(i=m;i<len;i++)
       if(!(str[i]==' ' || str[i]==9))
         str[m++]=str[i];
    str[m]='\0';
}
int main()
{
    int i,j,k,pos;
    string string1,string2;
    scanf("%d",&T);
    for(t=1;t<=T;t++)
    {
        if(t!=1)
          printf("\n");
        scanf("%d",&n);
        getchar();
        init();
        while(n--)
        {
            gets(str);
            solve();
            if(Over==1)
              continue;
            if(kong())
              continue;
            if(Has_Equal())
            {
                sscanf(str,"%s %s",s1,s2);
                if(s1[0]=='$')
                  type1=0;
                else
                  type1=1;
                if(s2[0]!=34)
                  type2=0;
                else
                  type2=1;
                if(type1==0)
                {
                    match[0].erase(s1);
                    match[1].erase(s1);
                    match[type2][s1]=s2;
                }
                else
                {
                    if(match[2].find(s1)==match[2].end() && match[3].find(s1)==match[3].end())
                      match[2+type2][s1]=s2;
                    else if(Err==1)
                      printf("WARNING: Constant %s Already Defined!\n",s1);
                }
            }
            else
            {
                sscanf(str,"%s %s",s1,s2);
                if(s1[0]=='P' && s1[1]=='a') //Panic
                {
                    printf("Script was KILLED.\n");
                    Over=1;
                }
                else if(s1[0]=='E' && s2[1]=='N') //Errmsg ON
                  Err=1;
                else if(s1[0]=='E' && s2[1]=='F') //Errmsg OFF
                  Err=0;
                else if(s1[0]=='P') //Print
                {
                    if(s2[0]=='$')
                    {
                        if(match[0].find(s2)!=match[0].end())
                        {
                            string1=match[0][s2];
                            cout<<string1<<endl;
                        }
                        else if(match[1].find(s2)!=match[1].end())
                        {
                            string1=match[1][s2];
                            string2=string1.substr(1,string1.length()-2);
                            cout<<string2<<endl;
                        }
                        else
                        {
                            printf("NULL\n");
                            if(Err==1)
                              printf("NOTICE: Undefined Variable %s.\n",s2);
                        }
                    }
                    else
                    {
                        if(match[2].find(s2)!=match[2].end())
                        {
                            string1=match[2][s2];
                            cout<<string1<<endl;
                        }
                        else if(match[3].find(s2)!=match[3].end())
                        {
                            string1=match[3][s2];
                            string2=string1.substr(1,string1.length()-2);
                            cout<<string2<<endl;
                        }
                        else
                        {
                            printf("%s\n",s2);
                            if(Err==1)
                              printf("NOTICE: Undefined Constant %s.\n",s2);
                        }
                    }
                }
                else if(s1[0]=='D') //Dump
                {
                    if(s2[0]=='$')
                    {
                        if(match[0].find(s2)!=match[0].end())
                        {
                            string1=match[0][s2];
                            printf("integer: ");
                            cout<<string1<<endl;
                        }
                        else if(match[1].find(s2)!=match[1].end())
                        {
                            string1=match[1][s2];
                            printf("string: ");
                            cout<<string1<<endl;
                        }
                        else
                        {
                            printf("NULL\n");
                            if(Err==1)
                              printf("NOTICE: Undefined Variable %s.\n",s2);
                        }
                    }
                    else
                    {
                        if(match[2].find(s2)!=match[2].end())
                        {
                            string1=match[2][s2];
                            printf("integer: ");
                            cout<<string1<<endl;
                        }
                        else if(match[3].find(s2)!=match[3].end())
                        {
                            string1=match[3][s2];
                            printf("string: ");
                            cout<<string1<<endl;
                        }
                        else
                        {
                            printf("string: %c%s%c\n",34,s2,34);
                            if(Err==1)
                              printf("NOTICE: Undefined Constant %s.\n",s2);
                        }
                    }
                }
            }
        }
    }
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

参考:http://blog.csdn.net/u014733623/article/details/45580607