news 2026/7/4 18:43:28

UVa 625 Compression

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
UVa 625 Compression

题目描述

本题要求实现一种简单的源代码压缩方法。源代码中出现的关键字(共161616个,见下文)被替换为&X形式,其中XXX是关键字对应的编号(000151515)。标识符(由字母和数字组成)中,长度≥3\ge 33的标识符会被编码为&X,其中XXX是该标识符的编号,从161616开始递增。但首次出现的标识符不进行替换(保留原样),仅将其映射关系存入内存,供后续出现时替换。长度小于333的标识符不编码。字符&不会出现在原始源代码中。输入文件可能包含多组数据,每组以单独一行end.结束。

输入格式

第一行为一个整数NNN,表示数据集的个数。随后可能有一个空行,然后依次是NNN个数据集。每个数据集包含若干行源代码,最后一行是end.(不含引号)。数据集之间可能有一个空行。

输出格式

对于每个数据集,输出压缩后的源代码,其中关键字和已见过的标识符被替换为相应代码,首次出现的标识符保持原样。每组输出之间以一个空行分隔。

样例

输入

1 program Test; var n :integer; function harmonic(number :integer):real; var i :integer; result :real; begin result := 0; for i := 1 to number do begin number := number + 1/i; end; harmonic := result; end; begin writeln('Get n:'); readln(n); writeln('harmonic number for n: '); writeln(harmonic(n)); end.

输出

program Test; &0 n :integer; &14 harmonic(number :&18):real; &0 i :&18; result :&21; &10 &22 := 0; &2 i := 1 to &20 do &10 &20 := &20 + 1/i; &1; &19 := &22; &1; &10 writeln('Get n:'); readln(n); &23(&19 &20 &2 n: '); &23(&19(n)); &1.

题目分析

压缩算法按以下规则处理源代码:

  1. 关键字:以下161616个关键字(全部小写)分别对应编号0∼150 \sim 15015
    var,end,for,then,else,case,goto,const,label,while,begin,until,repeat,downto,function,procedure
    遇到这些单词时,输出&编号

  2. 标识符:由字母和数字组成的连续字符串,且不能与关键字冲突。

    • 若长度<3< 3<3,则不编码,直接输出原始字符串。
    • 若长度≥3\ge 33,则查看该标识符是否已经出现过(即是否在映射表中)。
      • 若已出现过,则输出&编号(编号从161616开始递增)。
      • 若首次出现,则输出原始字符串,并将该标识符与一个递增编号(从161616开始)存入映射表。
  3. 其他字符(如标点符号、空格、数字、运算符等)原样输出。

注意:标识符可能包含数字,例如number33,应整体作为一个标识符处理。字符&不会出现在源文件中,因此不需要转义。

解题思路

  1. 预处理:读取数据集个数NNN,忽略可能存在的空行。

  2. 逐行处理:对于每个数据集,使用getline循环读取每一行,直到读到"end."为止。对于每一行,按字符扫描:

    • 若当前字符是字母或数字,则开始收集一个连续的单词(标识符或关键字)。
    • 收集完毕后,检查该单词是否在关键字映射表中:
      • 若是关键字,输出&编号
      • 否则,检查是否全由字母和数字组成(代码中进行了校验),并判断长度:
        • 长度<3< 3<3:直接输出原单词。
        • 长度≥3\ge 33:查询标识符映射表(vars),若存在则输出&编号;若不存在则将其加入映射表(编号递增),并输出原单词。
    • 若当前字符不是字母或数字,则直接输出该字符。
    • 注意处理行末换行:输出完当前行后,输出一个换行符。
  3. 数据集结束:读入"end."时,不进行压缩处理(因为end是关键字,但end.中的end应被替换为&1,而点号.原样保留),代码中直接输出&1.并结束该数据集。

  4. 输出格式:每组数据压缩后,若还有下一组,则输出一个空行分隔。

复杂度分析

  • 设源代码总字符数为LLL,标识符总数为KKKK≤2000K \le 2000K2000)。
  • 每个字符处理一次,每次查找关键字或标识符使用map\texttt{map}mapO(log⁡16)O(\log 16)O(log16)O(log⁡K)O(\log K)O(logK),总时间复杂度O(Llog⁡K)O(L \log K)O(LlogK)
  • 空间复杂度O(K)O(K)O(K),用于存储标识符映射。

代码实现

// Compression// UVa ID: 625// Verdict: Accepted// Submission Date: 2016-08-16// UVa Run Time: 0.000s//// 版权所有(C)2016,邱秋。metaphysis # yeah dot net#include<bits/stdc++.h>usingnamespacestd;intmain(){cin.tie(0);cout.tie(0);ios::sync_with_stdio(false);string line;getline(cin,line);intcases=stoi(line);map<string,int>keywords={{"var",0},{"end",1},{"for",2},{"then",3},{"else",4},{"case",5},{"goto",6},{"const",7},{"label",8},{"while",9},{"begin",10},{"until",11},{"repeat",12},{"downto",13},{"function",14},{"procedure",15}};for(intc=1;c<=cases;c++){if(c>1)cout<<'\n';getline(cin,line);map<string,int>vars;intcount=16;while(getline(cin,line),line!="end."){inti=0;while(i<line.length()){if(isalpha(line[i])||isdigit(line[i])){string block;while(i<line.length()&&(isalpha(line[i])||isdigit(line[i]))){block+=line[i];i++;}if(keywords.find(block)!=keywords.end())cout<<'&'<<keywords[block];else{boolalphanumeric=true;for(intj=0;j<block.length();j++)if(!isalpha(block[j])&&!isdigit(block[j])){alphanumeric=false;break;}if(alphanumeric){if(block.length()<3)cout<<block;else{if(vars.find(block)!=vars.end())cout<<'&'<<vars[block];else{vars[block]=count++;cout<<block;}}}elsecout<<block;}}elsecout<<line[i++];}cout<<'\n';}cout<<"&1.\n";}return0;}

总结

本题通过扫描源代码并按规则处理单词,实现了简单的压缩。关键在于:

  • 正确区分关键字和标识符,并处理好首次出现与后续出现的替换规则。
  • 注意标识符长度小于333时不编码。
  • 保持源代码中的空格、标点等非字母数字字符原样输出。
  • 注意数据集的结束标记end.,其中end需替换为&1

该题是字符串处理的典型应用,考察了对输入格式的理解和逐字符解析的能力。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/4 18:43:00

嵌入式系统中1-Wire EEPROM存储方案设计与实现

1. 项目背景与硬件选型解析在嵌入式系统开发中&#xff0c;持久化存储用户设置和偏好数据是一个基础但关键的需求。传统方案如Flash模拟EEPROM存在擦写次数限制&#xff08;通常约10万次&#xff09;&#xff0c;而外置独立EEPROM芯片则能提供更专业的数据存储解决方案。本项目…

作者头像 李华
网站建设 2026/7/4 18:42:54

CryFS加密文件系统深度解析:从AES-256到Twofish的完整安全架构与实战

1. 项目概述&#xff1a;为什么我们需要深入理解CryFS的加密内核&#xff1f;在数据安全领域&#xff0c;文件系统加密工具的选择往往决定了我们数据保护的“天花板”。CryFS&#xff0c;作为一个设计理念独特的加密文件系统&#xff0c;其核心价值不在于提供一个简单的“加密文…

作者头像 李华
网站建设 2026/7/4 18:41:27

使用74HC165与PIC18实现高效数字输入扩展方案

1. 项目背景与核心价值在工业控制和嵌入式系统开发中&#xff0c;我们经常需要处理大量数字输入信号。传统方案需要为每个输入信号分配独立的GPIO引脚&#xff0c;这不仅占用宝贵的微控制器资源&#xff0c;还会增加系统复杂度和布线成本。MC74HC165A这款8位并行输入/串行输出移…

作者头像 李华
网站建设 2026/7/4 18:40:58

AI不确定性管理:从概率认知到业务决策的实战指南

1. 这不是概念背诵清单&#xff0c;而是一份AI决策现场的“不确定性操作手册”你刚开完一场跨部门AI落地推进会&#xff0c;市场部要预测下季度爆款商品&#xff0c;供应链团队在纠结要不要提前锁定某类芯片的采购量&#xff0c;风控组则盯着新上线的信贷模型预警率持续攀升——…

作者头像 李华
网站建设 2026/7/4 18:40:36

多任务评测加权:平均分漂亮,不代表业务真的更好

多任务评测加权&#xff1a;平均分漂亮&#xff0c;不代表业务真的更好 一、简单平均会隐藏任务差异 多任务模型评测常把多个任务分数简单平均&#xff0c;得到一个总分。这个总分方便排序&#xff0c;但可能误导决策。任务难度不同、样本量不同、业务价值不同&#xff0c;简单…

作者头像 李华
网站建设 2026/7/4 18:40:03

AD74413R与PIC18F24K50实现高精度工业信号采集与输出

1. 项目背景与核心需求在工业控制和仪器仪表领域&#xff0c;同时实现高精度模拟信号采集&#xff08;ADC&#xff09;和输出&#xff08;DAC&#xff09;是常见需求。AD74413R作为ADI公司推出的软件可配置输入/输出器件&#xff0c;配合PIC18F24K50这类经济型MCU&#xff0c;能…

作者头像 李华