当前位置: 首页 > news >正文

UVa 189 Pascal Program Lengths

题目分析

本题要求计算Turbo Pascal\texttt{Turbo Pascal}Turbo Pascal程序的长度,长度由若干类token\texttt{token}token的数量决定,包括:

  • 保留字(reserved words\texttt{reserved words}reserved words
  • 标识符(identifiers\texttt{identifiers}identifiers
  • 常量(constants\texttt{constants}constants
  • 左括号(和左方括号[
  • 运算符:+-*/=<><=>=<>@^:=

需要特别注意的是:

  1. 注释:使用{}界定,不嵌套,注释内容完全忽略。
  2. 字符串常量:使用单引号'界定,字符串中的''表示一个单引号字符。
  3. 数字常量:包括整数、实数、科学计数法形式以及十六进制常量(以$开头)。
  4. 标识符:以字母或下划线_开头,后跟字母、数字或下划线。
  5. 子范围lower..upper形式中的..不是单独 token,而是两个.字符(但.不在计数范围内)。
  6. +-:尽可能视为运算符,例如x := -3中的-是运算符。

解题思路

本题的核心是对Pascal\texttt{Pascal}Pascal源代码进行一次扫描,识别出所有需要计数的token\texttt{token}token,同时忽略注释、字符串内容等其他字符。

一种可行的策略是多阶段扫描

  1. 预处理:将全部代码合并为一个字符串,并转换为小写,便于后续匹配保留字和标识符。
  2. 移除注释:扫描字符串,将{}之间的内容替换为空格。
  3. 处理字符串常量:扫描字符串,将''之间的内容替换为空格,同时注意''转义。遇到字符串常量时,需要为字符串本身计数111次(字符串常量属于常量的一种)。
  4. 计数括号和方括号:扫描字符串,遇到([则计数器加111,将这些字符替换为空格。
  5. 计数标识符和保留字:在begin之前的部分扫描标识符(因为变量声明只出现在begin之前),记录去重后的标识符列表,然后在全文中计数这些标识符的每次出现。
  6. 计数数字常量:扫描字符串,识别十六进制、整数、实数、科学计数法形式的数字常量,每次识别一个常量则计数器加111
  7. 计数运算符:依次匹配题目中给出的所有运算符,每次匹配成功则计数器加111
  8. 处理剩余标识符:扫描剩余字符串,识别可能遗漏的标识符(例如保留字)并计数。

最终输出格式为:Program by 姓名 contains 数量 units.

代码实现

// Pascal Program Lengths// UVa ID: 189// Verdict: Accepted// Submission Date: 2016-04-05// UVa Run Time: 0.000s//// 版权所有(C)2016,邱秋。metaphysis # yeah dot net#include<bits/stdc++.h>usingnamespacestd;// 存储整个程序的源代码string program;// 需要计数的运算符列表,按长度从长到短排列便于匹配string operators[13]={"<=",">=","<>",":=","@","^","+","-","*","/","=","<",">",};// 计算程序长度(单位数)intcount(){intcounter=0;// 统一转换为小写,便于后续匹配for(inti=0;i<program.length();i++)if(isalpha(program[i]))program[i]=tolower(program[i]);// 第一阶段:处理注释 {} 和字符串常量intindex=0;while(index<program.length()){// 处理注释if(program[index]=='{'){program[index++]=' ';while(index<program.length()){charcurrent=program[index];program[index]=' ';if(current=='}')break;index++;}}// 处理字符串常量elseif(program[index]=='\''){counter++;// 字符串常量作为一个 token 计数program[index++]=' ';while(index<program.length()){if(program[index]=='\''){// 两个连续单引号表示一个单引号字符,属于字符串内容if(program[index+1]=='\''){program[index]=' ';program[index+1]=' ';index+=2;}else{program[index]=' ';break;// 字符串结束}}elseprogram[index++]=' ';}}index++;}// 第二阶段:计数左括号和左方括号,右括号和右方括号忽略index=0;while(index<program.length()){if(program[index]=='('||program[index]=='['){counter++;program[index]=' ';}elseif(program[index]==')'||program[index]==']'){program[index]=' ';}index++;}// 第三阶段:在 BEGIN 之前收集标识符(变量名、类型名等)index=0;intlast=program.find("begin");if(last==program.npos)last=program.length();// 如果没有 begin,则扫描整个程序vector<string>variables;while(index<last){// 标识符:字母或下划线开头if(isalpha(program[index])||program[index]=='_'){string block;block+=program[index];counter++;// 每个标识符计数一次program[index++]=' ';while(index<last)if(isalpha(program[index])||isdigit(program[index])||program[index]=='_'){block+=program[index];program[index++]=' ';}elsebreak;variables.push_back(block);}index++;}// 第四阶段:在全文中查找这些标识符的每次出现并计数index=0;while(index<variables.size()){intnext=program.find(variables[index]);while(next!=program.npos){// 检查是否为独立单词(边界不是字母、数字、下划线)if(isalpha(program[next-1])==false&&isdigit(program[next-1])==false&&program[next-1]!='_'&&isalpha(program[next+variables[index].length()])==false&&isdigit(program[next+variables[index].length()])==false&&program[next+variables[index].length()]!='_'){counter++;for(inti=0;i<variables[index].length();i++)program[next+i]=' ';}next+=variables[index].length();next=program.find(variables[index],next);}index++;}// 第五阶段:处理数字常量index=0;while(index<program.length()){// 十六进制常量:以 $ 开头if(program[index]=='$'){counter++;program[index++]=' ';while(index<program.length()){charcurrent=program[index];if(isdigit(current)||(current>='a'&&current<='f'))program[index++]=' ';elsebreak;}}// 十进制数字常量(整数、实数、科学计数法)elseif(isdigit(program[index])){counter++;program[index++]=' ';// 整数部分while(index<program.length())if(isdigit(program[index]))program[index++]=' ';elsebreak;// 小数部分(可选)if(index<program.length()&&program[index]=='.'){program[index++]=' ';while(index<program.length())if(isdigit(program[index]))program[index++]=' ';elsebreak;}// 指数部分(可选)if(index<program.length()&&program[index]=='e'){program[index++]=' ';if(program[index]=='+'||program[index]=='-')program[index++]=' ';while(index<program.length()&&isdigit(program[index]))program[index++]=' ';}}index++;}// 第六阶段:处理运算符for(inti=0;i<13;i++){intstart=0;intnext=program.find(operators[i],start);while(next!=program.npos){counter++;for(intj=0;j<operators[i].length();j++)program[next+j]=' ';start=next+operators[i].length();next=program.find(operators[i],start);}}// 第七阶段:处理剩余的标识符(如保留字)index=0;while(index<program.length()){if(isalpha(program[index])||program[index]=='_'){counter++;program[index++]=' ';while(index<program.length())if(isalpha(program[index])||isdigit(program[index])||program[index]=='_')program[index++]=' ';elsebreak;}index++;}returncounter;}// 输出结果voidoutput(string name){intunits=count();cout<<"Program by "<<name<<" contains "<<units<<" units.\n";}intmain(){string line;while(getline(cin,line)){string firstTwoColumns=line.substr(0,2);// 遇到 ~~ 表示程序结束,输出结果并清空if(firstTwoColumns=="~~"){output(line.substr(2));program.clear();}else{// 将每行代码拼接,用空格分隔保证 token 边界正确program+=line;program+=' ';}}return0;}
http://www.jsqmd.com/news/783290/

相关文章:

  • 基于主动学习的广义Benders分解算法初始化优化研究
  • CANN/cann-bench: 加除乘复合算子
  • CANN/HCCL算法分析器使用指南
  • 2026办理腾讯企业邮箱服务,靠谱销售电话查询方式全解析 - 品牌2025
  • AI道德地位:从工具到伙伴的认知转变与设计伦理
  • Balena Etcher终极指南:三分钟学会安全烧录系统镜像
  • 基于SVR与特征选择的系外行星半径预测:数据清洗、模型构建与天文解读
  • Python发布成AIP接口服务的几种方式
  • 非洲AI本土化实践:医疗、农业、金融、教育四大领域创新与挑战
  • 信贷风控中可解释AutoML实践:用SHAP与H2O实现透明AI决策
  • 2026年成都水刀配件厂家与水刀易损件采购完全指南:源头厂商直达+品牌深度横评 - 企业名录优选推荐
  • 2026数据资产入表解决方案(52页 PPT)
  • 零基础部署 OpenClaw v2.7.1,自动化操作电脑
  • chatgpt入口 chatgpt的一些python调用方法
  • 贵阳新房装修怎么选?5大中高端室内设计公司对比与选购指南 - 优质企业观察收录
  • 2026年贵阳室内全案设计与精装整装深度横评:五大品牌设计落地与工程保障对标指南 - 优质企业观察收录
  • 第五篇:锻造大脑——为什么算法公开,你却造不出 GPT?
  • 天津祥和景观工程:红桥景观花镜设计公司有哪些 - LYL仔仔
  • 联邦学习与Transformer在CV与安全领域的融合应用与实战解析
  • 国产OpenClaw智能体推荐:企业级国产OpenClaw智能体厂商全解析 - 品牌2025
  • 网盘直链下载助手完整指南:告别限速,解锁九大网盘真实下载链接
  • CANN 全国挑战赛 2025
  • 分析原设计的问题
  • 微波马弗炉推荐品牌及核心参数解析 - 品牌推荐大师
  • VADER框架:将模糊AI法规转化为可量化技术指标的方法论
  • 广州亿源贸易商行:南沙茅台回收公司 - LYL仔仔
  • 长期使用中观察到的Taotoken账单明细与成本分析价值
  • CANN/cann-learning-hub:HIXL在RL推理中的长尾时延优化
  • CANN/hccl集合通信AlltoAllVC
  • 终极APA第7版格式转换指南:3分钟解决学术论文引用难题