首页 > 其他分享 >UVA12421 (Jiandan) Mua (I) - Lexical Analyzer 题解

UVA12421 (Jiandan) Mua (I) - Lexical Analyzer 题解

时间:2024-02-23 20:55:07浏览次数:18  
标签:ch return && int 题解 Lexical Analyzer ch1 str

蒟蒻的第一篇紫题题解!

题目传送门

思路

一眼模拟,还是大模拟。不由得想起了我编了 \(4\) 个小时的猪国杀……

输入

首先处理输入,这里我们用一个字符串数组来存储所有的输入,然后再进行处理。

while(getline(cin,sr))str[++cnt]=sr+'\n';

处理时需要双重循环,注意如果遍历到空格要跳过!(字符串内除外)

换行符在第一层循环末尾输出即可。

NUMBER

我们从最难处理的数字开始。

首先判断有没有 .,再判断是不是十六进制,然后再逐个往后筛,看看能否加进这个数字中,用一个字符串 \(ans\) 来储存答案,记得在最后清零!

bool checknum(int x,int y){
    char ch=str[x][y];
    if(ch>='0'&&ch<='9'||ch=='e'||ch>='A'&&ch<='F'||ch>='a'&&ch<='f')return 1;
    if(ch=='-'||ch=='+')if(str[x][y-1]=='e')return 1;else return 0;
    if(ch=='.'&&!pd){pd=1;return 1;}
    return 0;
}

if(str[i][j]>='0'&&str[i][j]<='9'||str[i][j]=='.'&&str[i][j+1]>='0'&&str[i][j+1]<='9'){
    cout<<"[NUMBER] ";pd=0;
    if(str[i][j]=='.')ans+=str[i][j],j++,pd=1;
    if(str[i][j]=='0'&&(str[i][j+1]=='X'||str[i][j+1]=='x'))ans+=str[i][j],ans+=str[i][j+1],j+=2,pd=1;
    while(checknum(i,j))ans+=str[i][j],j++;j--;
    cout<<ans<<'\n';
    ans="";
}

STRING

接着我们再来看如何处理字符串。

如果碰到 '",就将从这个字符往后筛直到找到另一个 '",不过如果这个 '" 前一个字符是 \,则需跳过继续往后筛。

bool checkstring(int x,int y,char tmp){
    char ch1=str[x][y],ch2=str[x][y-1];
    if(tmp!=ch1)return 1;
    else{if(ch2=='\\')return 1;else return 0;}
    return 0;
}

if(str[i][j]=='\''||str[i][j]=='\"'){
    cout<<"[STRING] ";
    ans+=str[i][j];
    char tmp=str[i][j];j++;
    while(checkstring(i,j,tmp))ans+=str[i][j],j++;
    ans+=str[i][j];
    cout<<ans<<'\n';
    ans="";
}

SYMBOL

然后就是符号了。

直接用一个函数判断就行,但要注意先判断长度长的,避免重复。

int checksymbol(int x,int y){
    char ch1=str[x][y],ch2=str[x][y+1];
    if(ch1=='.'&&ch2=='.'&&str[x][y+2]=='.')return 3;
    if(ch1=='.'&&ch2=='.'||ch1=='='&&ch2=='='||ch1=='>'&&ch2=='='||ch1=='<'&&ch2=='='||ch1=='~'&&ch2=='=')return 2;
    /*+ - * / % ^ # == >= <= > < ~= ( ) { } [ ] ; : , . .. ... =*/
    if(ch1=='.'||ch1==','||ch1==':'||ch1==';'||ch1=='='||ch1=='+'||ch1=='-'||ch1=='*'||ch1=='/'||ch1=='%'||ch1=='^'||ch1=='#'||ch1=='<'||ch1=='>'||ch1=='('||ch1==')'||ch1=='{'||ch1=='}'||ch1=='['||ch1==']')return 1;
    return 0;
}

if(checksymbol(i,j)){
    int tmp=checksymbol(i,j);
    cout<<"[SYMBOL] ";
    for(int k=0;k<tmp;k++)ans+=str[i][j+k];
    j+=tmp,j--;
    cout<<ans<<'\n';
    ans="";
}

NAME&&RESERVED

保留字可以在名称里判断。

先找到一个字母,然后往后滤,只要后一个字符是字母、数字、下划线中的一个就压入 \(ans\) 中,最后整体判断 \(ans\) 属不属于保留字即可。

bool checkname(int x,int y){
    char ch=str[x][y];
    if(ch>='0'&&ch<='9'||ch>='a'&&ch<='z'||ch>='A'&&ch<='Z'||ch=='_')return 1;
    return 0;
}

bool checkreserved(string s){
    for(int i=0;i<21;i++)if(s==RESERVED[i])return 1;
    return 0;
}

if(str[i][j]>='a'&&str[i][j]<='z'||str[i][j]>='A'&&str[i][j]<='Z'){
    while(checkname(i,j))ans+=str[i][j],j++;j--;
    if(checkreserved(ans))cout<<"[RESERVED] "<<ans<<'\n';
    else cout<<"[NAME] "<<ans<<'\n';
    ans="";
}

COMMENT

只需要判断有没有两个连续的 _,然后把后面的全部刨去,注意要输出换行符!

if(str[i][j]=='-'&&str[i][j+1]=='-')j=len-1;

完整代码

#include<bits/stdc++.h>
using namespace std;
string RESERVED[25]={"and","break","do","else","elseif","end","false","for","function","if","in","local","nil","not","or","repeat","return","then","true","until","while"};
string sr,str[1005],ans;
int cnt,len,j;
bool pd;
bool checknum(int x,int y){
    char ch=str[x][y];
    if(ch>='0'&&ch<='9'||ch=='e'||ch>='A'&&ch<='F'||ch>='a'&&ch<='f')return 1;
    if(ch=='-'||ch=='+')if(str[x][y-1]=='e')return 1;else return 0;
    if(ch=='.'&&!pd){pd=1;return 1;}
    return 0;
}
bool checkstring(int x,int y,char tmp){
    char ch1=str[x][y],ch2=str[x][y-1];
    if(tmp!=ch1)return 1;
    else{if(ch2=='\\')return 1;else return 0;}
    return 0;
}
int checksymbol(int x,int y){
    char ch1=str[x][y],ch2=str[x][y+1];
    if(ch1=='.'&&ch2=='.'&&str[x][y+2]=='.')return 3;
    if(ch1=='.'&&ch2=='.'||ch1=='='&&ch2=='='||ch1=='>'&&ch2=='='||ch1=='<'&&ch2=='='||ch1=='~'&&ch2=='=')return 2;
    /*+ - * / % ^ # == >= <= > < ~= ( ) { } [ ] ; : , . .. ... =*/
    if(ch1=='.'||ch1==','||ch1==':'||ch1==';'||ch1=='='||ch1=='+'||ch1=='-'||ch1=='*'||ch1=='/'||ch1=='%'||ch1=='^'||ch1=='#'||ch1=='<'||ch1=='>'||ch1=='('||ch1==')'||ch1=='{'||ch1=='}'||ch1=='['||ch1==']')return 1;
    return 0;
}
bool checkname(int x,int y){
    char ch=str[x][y];
    if(ch>='0'&&ch<='9'||ch>='a'&&ch<='z'||ch>='A'&&ch<='Z'||ch=='_')return 1;
    return 0;
}
bool checkreserved(string s){
    for(int i=0;i<21;i++)if(s==RESERVED[i])return 1;
    return 0;
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    while(getline(cin,sr))str[++cnt]=sr+'\n';
    for(int i=1;i<=cnt;i++){
        ans="";
        len=str[i].length();
        // cout<<str[i];
        for(int j=0;j<len;j++){
            if(str[i][j]==' ')continue;
            else if(str[i][j]=='-'&&str[i][j+1]=='-')j=len-1;
            else if(str[i][j]>='0'&&str[i][j]<='9'||str[i][j]=='.'&&str[i][j+1]>='0'&&str[i][j+1]<='9'){
                cout<<"[NUMBER] ";pd=0;
                if(str[i][j]=='.')ans+=str[i][j],j++,pd=1;
                if(str[i][j]=='0'&&(str[i][j+1]=='X'||str[i][j+1]=='x'))ans+=str[i][j],ans+=str[i][j+1],j+=2,pd=1;
                while(checknum(i,j))ans+=str[i][j],j++;j--;
                cout<<ans<<'\n';
                ans="";
            }else if(str[i][j]=='\''||str[i][j]=='\"'){
                cout<<"[STRING] ";
                ans+=str[i][j];
                char tmp=str[i][j];j++;
                while(checkstring(i,j,tmp))ans+=str[i][j],j++;
                ans+=str[i][j];
                cout<<ans<<'\n';
                ans="";
            }else if(checksymbol(i,j)){
                int tmp=checksymbol(i,j);
                cout<<"[SYMBOL] ";
                for(int k=0;k<tmp;k++)ans+=str[i][j+k];
                j+=tmp,j--;
                cout<<ans<<'\n';
                ans="";
            }else if(str[i][j]>='a'&&str[i][j]<='z'||str[i][j]>='A'&&str[i][j]<='Z'){
                while(checkname(i,j))ans+=str[i][j],j++;j--;
                if(checkreserved(ans))cout<<"[RESERVED] "<<ans<<'\n';
                else cout<<"[NAME] "<<ans<<'\n';
                ans="";
            }
        }
        cout<<"[EOL]\n";
    }
    return 0;
}

标签:ch,return,&&,int,题解,Lexical,Analyzer,ch1,str
From: https://www.cnblogs.com/MithrilSwordXIV/p/18030353

相关文章

  • CF916E Jamie and Tree 题解
    题目链接:CF或者洛谷本题难点在于换根LCA与换根以后的子树范围寻找,重点讲解先说操作一,假如原根为\(1\)变为了\(x\),又变为了\(y\),那么其实\(y\)和\(x\)都可以看做由\(1\)变化而来的,即\(1\rightarrowx\)与\(1\rightarrowy\),原因很简单,我们可以把\(1\rightar......
  • P9901 『PG2』弯曲半平面直线同向图最大流 题解
    思路正解想不出,只好用网络流了网络流简介请戳这儿。这道题数据有点大用EK求最大流似乎过不了,所以本蒟蒻采用Dinic算法。Dinic算法Dinic算法相当于EK的优化。在原基础找增广路的基础上添加了一个分层操作,再通过深搜找阻塞流。分层从原点开始我们把可以通过一步到达的......
  • 记录pyinstaller 打包 pdfplumber 问题解决过程
    今天有一个pdf文件处理需求,使用pdfplumber库完成,python环境是3.11+win10pyinstaller5.10.1打包完成后,工具可以顺利打开,但是执行处理的时候报错File"pypdfium2_raw\bindings.py",line93,in<module>File"pypdfium2_raw\bindings.py",line83,in_register_library......
  • blazor 问题解决
    Cannotprovideavalueforproperty'ScrollToLocationHash'ontype'Microsoft.AspNetCore.Components.Routing.Router'.Thereisnoregisteredserviceoftype'Microsoft.AspNetCore.Components.Routing.IScrollToLocationHash'.异常信息......
  • Jenkins构建提示docker命令权限问题解决方法
    参考:https://zhuanlan.zhihu.com/p/568513293使用Jenkins构建时使用的用户为jenkins在使用docker命令时会报以下错误ERROR:permissiondeniedwhiletryingtoconnecttotheDockerdaemonsocketatunix:///var/run/docker.sock:Get"http://%2Fvar%2Frun%2Fdocker.soc......
  • P6646 [CCO2020] Shopping Plans 题解
    好好玩的题。思路对于前\(K\)小方案问题。我们可以考虑当前方案对下一个方案的转移。重点在于转移的最优化与不重不漏。只有一种种类假设没有\(l,r\)的限制怎么做。我们不妨把所有价格排序。发现一种状态转移到另一种状态,无异与将其中已选择的一个物品不选,选择他后面......
  • process.env.API_KEY undefined问题解决
    问题现象已经在root路径下面创建.env文件,但是使用process.env.API_KEY获取不到值。分析获取不到env文件中的值,检查env文件已配置API_KEY,检查是否安装了dotenv,检查是否导入配置了dotenv解决方法在index.ts中导入import'dotenv/config';应该在使用env的模块前面就导入dote......
  • 2024.2.22模拟赛T3 题解
    对于区间连边,可以线段树优化建图对于单点连边,可以使用李超线段树维护迪杰斯特拉code#include<bits/stdc++.h>usingnamespacestd;#defineN400005#defineintlonglong#definepiipair<int,int>#definefirfirst#definesecsecondintn,m,tot;intval[N];const......
  • 数星星题解补充
    题解中那个看似暴力的染色,实际上正确性显然,直接看75%的时间复杂度证明然后还是直接看75分的部分它的里面说是用set维护块的前驱后继,然后全网没有一篇这样的题解,似乎全世界就我一个用这个方法于是想了一中午终于想到如何维护:就是用set记录每一个块的最后一个的位置,由于是区间覆......
  • P3870 分块题解
    这篇题解有点问题(分块标记处),但现在不想修,等有空修吧link分块是一种很神奇的暴力,学了它就会觉得什么都可以用分块做。分块的主要思想就是整块快速查询,散块暴力查询。比如说,分块可以在\(O(q\sqrt{n}+n)\)的时间复杂度内解决线段树模板题。回到本题,显然我们可以用每个块维护......