UVa 134 Loglan A Logical Language

题目描述

Loglan\texttt{Loglan}Loglan是一种人造的逻辑语言,用于测试语言学中的一些基本问题(如Sapir-Whorf\texttt{Sapir-Whorf}Sapir-Whorf假设)。它的语法明确,文化中立,形而上简洁。题目要求判断给定的字符串是否为合法的Loglan\texttt{Loglan}Loglan句子。

句子由单词和名字组成,以句点.结束。单词以元音结尾,名字以辅音结尾。单词分为两类:

  • 小词(little words\texttt{little words}little words:定义句子结构。
  • 谓词(predicates\texttt{predicates}predicates:形式为CCVCVCVCCV,其中C表示辅音,V表示元音。

给出的语法规则如下(已简化):

A ⇒ a | e | i | o | u MOD ⇒ ga | ge | gi | go | gu BA ⇒ ba | be | bi | bo | bu DA ⇒ da | de | di | do | du LA ⇒ la | le | li | lo | lu NAM ⇒ {all names} PREDA ⇒ {all predicates} <sentence> ⇒ <statement> | <predclaim> <predclaim> ⇒ <predname> BA <preds> | DA <preds> <preds> ⇒ <predstring> | <preds> A <predstring> <predname> ⇒ LA <predstring> | NAM <predstring> ⇒ PREDA | <predstring> PREDA <statement> ⇒ <predname> <verbpred> <predname> | <predname> <verbpred> <verbpred> ⇒ MOD <predstring>

输入:多个句子,每句以.结尾,输入以#结束。句子可跨行,单词间可有多个空格。

输出:对每个句子输出GoodBad!

解题思路

本题是一个语法分析问题,适合使用自顶向下自底向上的解析方法。由于规则较为复杂且涉及递归,我们可以采用递归下降表驱动的解析方法。

关键点分析

  1. 单词分类:首先需要识别每个单词的类型(如AMODBADALANAMPREDA)。
  2. 递归结构:多个语法规则是递归定义的,例如<preds><predstring>
  3. 句子结构:最终句子要么是<statement>,要么是<predclaim>

方法选择

两种实现代码都使用了自顶向下的递归判断,但实现方式不同:

  • 第一种:为每个语法规则编写独立的判断函数,通过递归和拆分单词向量进行验证。
  • 第二种:使用表驱动的方法,将规则编码在表中,通过状态转换进行归约,类似于一个简单的下推自动机

算法步骤(以第一种为例)

  1. 读取输入:按行读入,去掉句点,分割单词。
  2. 分类判断
    • isPREDA(word):检查是否为CCVCVCVCCV
    • isPredstring(words):检查是否全部为PREDA
    • isPreds(words):递归检查<preds>结构。
    • isPredname(words):检查LA <predstring>NAM
    • isStatement(words):检查<predname> <verbpred> <predname><predname> <verbpred>
    • isPredclaim(words):检查<predname> BA <preds>DA <preds>
  3. 最终判断:句子为<statement><predclaim>即合法。

代码实现

第一种:递归函数法

// Loglan-A Logical Language// UVa ID: 134// Verdict: Accepted// Submission Date: 2016-01-01// UVa Run Time: 0.000s//// 版权所有(C)2016,邱秋。metaphysis # yeah dot net#include<bits/stdc++.h>usingnamespacestd;// A => a | e | i | o | uboolisA(charc){string vowel="aeiou";returnvowel.find(c)!=string::npos;}// MOD => ga | ge | gi | go | guboolisMOD(string word){returnword.length()==2&&word[0]=='g'&&isA(word[1]);}// BA => ba | be | bi | bo | buboolisBA(string word){returnword.length()==2&&word[0]=='b'&&isA(word[1]);}// DA => da | de | di | do | duboolisDA(string word){returnword.length()==2&&word[0]=='d'&&isA(word[1]);}// LA => la | le | li | lo | luboolisLA(string word){returnword.length()==2&&word[0]=='l'&&isA(word[1]);}// NAM => { all names },最后一个字母为辅音字母。boolisNAM(string word){return!isA(word.at(word.length()-1));}// PREDA => { all predicates },满足 CCVCV 或者 CVCCV 的模式,C 为辅音字母,// V 为元音字母。使用位操作,将字符位置编为一个二进制数进行判断。boolisPREDA(string word){if(word.length()!=5)returnfalse;intbitOr=0;for(inti=0;i<5;i++)bitOr|=((isA(word[i])?1:0)<<(4-i));return(bitOr==5||bitOr==9);}// <predstring> => PREDA | <predstring> PREDAboolisPredstring(vector<string>words){if(words.size()==0)returnfalse;for(inti=0;i<words.size();i++)if(!isPREDA(words[i]))returnfalse;returntrue;}// <preds> => <predstring> | <preds> A <predstring>boolisPreds(vector<string>words){if(words.size()==0)returnfalse;// 找到起始的 PREDA 或 Afor(inti=words.size()-1;i>=0;i--){if(isPREDA(words[i]))continue;elseif(words[i].length()==1&&isA(words[i][0])){if(i>0){vector<string>preds(words.begin(),words.begin()+i);returnisPreds(preds);}elsereturnfalse;}elsereturnfalse;}returntrue;}// <predname> => LA <predstring> | NAMboolisPredname(vector<string>words){if(words.size()==0)returnfalse;if(!isLA(words.front())&&!isNAM(words.front()))returnfalse;if(words.size()==1&&isNAM(words.front()))returntrue;if(isLA(words.front())){vector<string>predstring(words.begin()+1,words.end());returnisPredstring(predstring);}elsereturnfalse;returntrue;}// <statement> => <predname> <verbpred> <predname> | <predname> <verbpred>boolisStatement(vector<string>words){// 找到 <verbpred>inti,j;for(i=0;i<=(words.size()-2);i++)if(isMOD(words.at(i))){// 提取 <verbpred> 之前的 <predname>vector<string>predname(words.begin(),words.begin()+i);// 找到构成 <verbpred> 在 MOD 之后的所有 PREDA,若未到 words 的末端,// 则句子可能是 statement 的第一种模式,否则可能是第二种模式for(j=i+1;j<words.size();j++)if(!isPREDA(words[j]))break;if(j<(words.size()-1)){vector<string>nextPredname(words.begin()+j,words.end());returnisPredname(predname)&&isPredname(nextPredname);}elsereturnisPredname(predname);}returnfalse;}// <predclaim> => <predname> BA <preds> | DA <preds>boolisPredclaim(vector<string>words){// DA <preds>if(isDA(words.front())){vector<string>preds(words.begin()+1,words.end());returnisPreds(preds);}// <predname> BA <preds>for(inti=0;i<words.size();i++){if(isBA(words[i])){vector<string>predname(words.begin(),words.begin()+i);vector<string>preds(words.begin()+i+1,words.end());returnisPredname(predname)&&isPreds(preds);}}returnfalse;}// <sentence> => <statement> | <predclaim>boolisSentence(vector<string>words){if(words.size()==0)returnfalse;returnisStatement(words)||isPredclaim(words);}intmain(){vector<string>words;string line,word;while(getline(cin,line),line!="#"){// 读入字符串,将其转换为单词数组以便判定。stringnewLine(line);if(line.find('.')!=string::npos)newLine=newLine.substr(0,newLine.find('.'));istringstreamiss(newLine);while(iss>>word)words.push_back(word);if(line.find('.')!=string::npos){cout<<(isSentence(words)?"Good":"Bad!")<<endl;words.clear();}}return0;}

第二种:表驱动法

// Loglan-A Logical Language// UVa ID: 134// Verdict: Accepted// Submission Date: 2016-04-12// UVa Run Time: 0.000s//// 版权所有(C)2016,邱秋。metaphysis # yeah dot net#include<bits/stdc++.h>usingnamespacestd;constintGROUPS=14;constintNONE=-1,A=0,MOD=1,BA=2,DA=3,LA=4,NAM=5,PREDA=6,PREDSTRING=7,PREDNAME=8,PREDS=9,VERBPRED=10,PREDVERB=11,PREDCLAIM=12,STATEMENT=13,SENTENCE=14;vector<int>S;vector<string>W;intT[GROUPS][4]={{PREDA,NONE,PREDA,PREDA},{PREDA,NONE,NONE,PREDSTRING},{NAM,NONE,NONE,PREDNAME},{LA,NONE,PREDSTRING,PREDNAME},{MOD,NONE,PREDSTRING,VERBPRED},{A,PREDSTRING,PREDSTRING,PREDSTRING},{PREDSTRING,NONE,NONE,PREDS},{DA,NONE,PREDS,PREDCLAIM},{BA,PREDNAME,PREDS,PREDCLAIM},{VERBPRED,PREDNAME,NONE,PREDVERB},{PREDVERB,NONE,PREDNAME,STATEMENT},{PREDVERB,NONE,NONE,STATEMENT},{STATEMENT,NONE,NONE,SENTENCE},{PREDCLAIM,NONE,NONE,SENTENCE}};intgetSymbol(string word){string vowel="aeiou";if(word.length()==1&&vowel.find(word[0])!=word.npos)returnA;if(word.length()==2&&vowel.find(word[1])!=word.npos){if(word[0]=='g')returnMOD;if(word[0]=='b')returnBA;if(word[0]=='d')returnDA;if(word[0]=='l')returnLA;returnNONE;}if(vowel.find(word.back())==word.npos)returnNAM;if(word.length()==5){intbitOr=0;for(inti=0;i<5;i++)bitOr|=((vowel.find(word[i])!=word.npos?1:0)<<(4-i));if(bitOr==5||bitOr==9)returnPREDA;}returnNONE;}boolparse(){S.clear();for(inti=0;i<W.size();i++){intsymbol=getSymbol(W[i]);if(symbol==NONE)returnfalse;elseS.push_back(symbol);}returntrue;}boolgood(){if(!parse())returnfalse;for(inti=0;i<GROUPS;i++)for(intj=0;j<S.size();){if((S[j]!=T[i][0])||(~T[i][1]&&(!j||S[j-1]!=T[i][1]))||(~T[i][2]&&(j==(S.size()-1)||S[j+1]!=T[i][2]))){j++;continue;}j=~T[i][1]?S.erase(S.begin()+j-1)-S.begin():j;j=~T[i][2]?S.erase(S.begin()+j+1)-S.begin()-1:j;S[j]=T[i][3];}return(S.size()==1&&S[0]==SENTENCE);}intmain(){string line,word;while(getline(cin,line),line!="#"){stringtemp(line);if(line.find('.')!=string::npos)temp=temp.substr(0,temp.find('.'));istringstreamiss(temp);while(iss>>word)W.push_back(word);if(line.find('.')!=string::npos){cout<<(good()?"Good":"Bad!")<<endl;W.clear();}}return0;}

总结

本题考察了语法分析的基本能力,适合作为编译原理的练习题。两种解法各有特点:

  • 递归函数法:直观易理解,适合规则较少的情况。
  • 表驱动法:代码简洁,易于扩展,适合规则较多且结构清晰的情况。

在实际解题时,建议先理解语法规则,再选择合适的解析方法。本题的难点在于递归规则的判断和单词类型的准确识别。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1139000.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python程序打包神器:PyInstaller终极使用指南

Python程序打包神器&#xff1a;PyInstaller终极使用指南 【免费下载链接】pyinstaller Freeze (package) Python programs into stand-alone executables 项目地址: https://gitcode.com/gh_mirrors/py/pyinstaller 你是否曾经遇到过这样的困扰&#xff1a;开发了一个实…

Qwen3-VL-WEBUI边缘计算:端侧部署延迟优化实战

Qwen3-VL-WEBUI边缘计算&#xff1a;端侧部署延迟优化实战 1. 引言&#xff1a;端侧多模态推理的现实挑战 随着大模型从云端向边缘设备下沉&#xff0c;低延迟、高响应性成为决定用户体验的关键指标。Qwen3-VL-WEBUI 作为阿里开源的视觉-语言一体化推理前端&#xff0c;内置 …

o-lib开源图书管理工具:从入门到精通的完整指南

o-lib开源图书管理工具&#xff1a;从入门到精通的完整指南 【免费下载链接】o-lib O-LIB is a free and open source software for PC. 项目地址: https://gitcode.com/gh_mirrors/ol/o-lib 在数字化阅读时代&#xff0c;如何高效管理个人图书收藏成为许多读者的迫切需…

DeepFaceLive实时面部交换终极指南:从零基础到精通应用

DeepFaceLive实时面部交换终极指南&#xff1a;从零基础到精通应用 【免费下载链接】DeepFaceLive Real-time face swap for PC streaming or video calls 项目地址: https://gitcode.com/GitHub_Trending/de/DeepFaceLive 想要在视频会议中制造惊喜&#xff0c;或在直播…

Python机器学习实战:5个关键算法解决材料科学预测难题

Python机器学习实战&#xff1a;5个关键算法解决材料科学预测难题 【免费下载链接】Python All Algorithms implemented in Python 项目地址: https://gitcode.com/GitHub_Trending/pyt/Python 您是否曾经为材料性能预测的复杂性而困扰&#xff1f;&#x1f914; 面对海…

Python数据类型在数据分析中的实战应用

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个数据分析脚本&#xff0c;使用Python处理销售数据。要求&#xff1a;1) 使用字典存储产品信息&#xff08;名称、价格、库存&#xff09;&#xff1b;2) 用列表存储订单记…

Whisper-medium.en英语语音识别终极指南:从入门到精通实战技巧

Whisper-medium.en英语语音识别终极指南&#xff1a;从入门到精通实战技巧 【免费下载链接】whisper-medium.en 项目地址: https://ai.gitcode.com/hf_mirrors/openai/whisper-medium.en 还在为英语语音转文字而烦恼吗&#xff1f;&#x1f914; 无论是会议记录、课程转…

Qwen3-VL-WEBUI部署优化:GPU资源配置最佳实践

Qwen3-VL-WEBUI部署优化&#xff1a;GPU资源配置最佳实践 1. 背景与技术定位 随着多模态大模型在视觉理解、语言生成和跨模态推理能力上的持续突破&#xff0c;Qwen3-VL 系列成为当前最具代表性的视觉-语言模型之一。作为阿里云开源的旗舰级多模态模型&#xff0c;Qwen3-VL-W…

Skyvern智能浏览器自动化技术深度解析:架构设计与企业级应用实践

Skyvern智能浏览器自动化技术深度解析&#xff1a;架构设计与企业级应用实践 【免费下载链接】skyvern 项目地址: https://gitcode.com/GitHub_Trending/sk/skyvern Skyvern作为一款基于大语言模型和计算机视觉技术的智能浏览器自动化平台&#xff0c;正在彻底改变传统…

Qwen3-VL UI设计:从需求到代码生成指南

Qwen3-VL UI设计&#xff1a;从需求到代码生成指南 1. 背景与核心价值 1.1 视觉语言模型的演进需求 随着多模态AI在内容理解、智能代理和人机交互中的广泛应用&#xff0c;单一文本大模型已难以满足复杂场景下的综合推理需求。阿里推出的 Qwen3-VL 系列标志着视觉-语言融合能…

Qwen3-VL空间推理:具身AI支持部署案例

Qwen3-VL空间推理&#xff1a;具身AI支持部署案例 1. 引言&#xff1a;Qwen3-VL-WEBUI与具身AI的融合实践 随着多模态大模型在真实世界交互中的需求日益增长&#xff0c;空间感知能力已成为连接语言理解与物理环境操作的关键桥梁。阿里最新推出的 Qwen3-VL-WEBUI 开源项目&am…

微任务到底是个啥?前端老铁别再被Promise.then绕晕了!

微任务到底是个啥&#xff1f;前端老铁别再被Promise.then绕晕了&#xff01;微任务到底是个啥&#xff1f;前端老铁别再被Promise.then绕晕了&#xff01;先整点刺激的&#xff0c;把你按在地上摩擦微任务到底是个啥&#xff1f;前端老铁别再被Promise.then绕晕了&#xff01;…

JProfiler零基础入门:5分钟搞定第一个性能分析

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个交互式JProfiler入门教程应用&#xff0c;包含一个预设的简单Java程序&#xff08;如存在明显内存泄漏的示例&#xff09;。引导用户完成安装JProfiler、连接应用、执行基…

终极指南:如何使用bilidown轻松下载哔哩哔哩高清视频

终极指南&#xff1a;如何使用bilidown轻松下载哔哩哔哩高清视频 【免费下载链接】bilidown 哔哩哔哩视频解析下载工具&#xff0c;支持 8K 视频、Hi-Res 音频、杜比视界下载、批量解析&#xff0c;可扫码登录&#xff0c;常驻托盘。 项目地址: https://gitcode.com/gh_mirro…

SpringBoot3+Vue3全栈开发:从零搭建企业级应用完整教程

SpringBoot3Vue3全栈开发&#xff1a;从零搭建企业级应用完整教程 【免费下载链接】SpringBoot3-Vue3-Demo 由我本人独立研发的一个基于 Spring Boot 3 和 Vue 3 的全栈示例项目&#xff0c;后端使用 MyBatis、MySQL 和本地缓存构建了高效的数据访问层&#xff0c;前端采用 Vue…

AI助力SVG图形生成:5分钟打造专业矢量图

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个基于AI的SVG图形生成工具&#xff0c;用户可以通过自然语言描述想要的图形&#xff08;如生成一个蓝色的圆形&#xff0c;半径50px&#xff0c;带有红色边框&#xff09;&…

AI一键搞定Vue环境搭建,告别繁琐配置

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个基于Vue3的电商后台管理系统前端项目&#xff0c;使用TypeScriptPiniaVite技术栈&#xff0c;要求包含以下功能&#xff1a;1.自动配置axios拦截器 2.集成Element Plus组件…

Qwen3-VL-WEBUI部署教程:从零开始搭建视觉语言模型平台

Qwen3-VL-WEBUI部署教程&#xff1a;从零开始搭建视觉语言模型平台 1. 引言 1.1 学习目标 本文将带你从零开始完整部署 Qwen3-VL-WEBUI&#xff0c;构建一个支持图像理解、视频分析、GUI操作与多模态推理的视觉语言模型交互平台。完成本教程后&#xff0c;你将能够&#xff…

终极PDF段落拼接指南:轻松解决跨页文档转换难题

终极PDF段落拼接指南&#xff1a;轻松解决跨页文档转换难题 【免费下载链接】MinerU A high-quality tool for convert PDF to Markdown and JSON.一站式开源高质量数据提取工具&#xff0c;将PDF转换成Markdown和JSON格式。 项目地址: https://gitcode.com/GitHub_Trending/…

BusyBox vs 完整工具集:嵌入式开发效率对比实验

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个自动化测试平台&#xff0c;能够&#xff1a;1) 在相同硬件环境下并行安装标准Linux工具集和BusyBox 2) 执行预定义的测试脚本&#xff08;文件操作、文本处理、网络测试等…