news 2026/5/21 0:33:29

UVa 245 Uncompress

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
UVa 245 Uncompress

题目分析

本题要求实现一个解压缩程序,根据给定的压缩文件恢复原始文件。压缩规则如下:

  1. 原始文件中包含单词(连续的字母序列)和非字母字符。
  2. 对于第一次出现的单词,直接输出该单词,并将其放入一个列表中(放在列表最前面)。
  3. 对于后续出现的单词,不输出单词本身,而是输出该单词在列表中的位置(从1 11开始编号),然后将该单词移动到列表最前面。
  4. 非字母字符(如标点符号、空格、换行等)直接原样输出,不进行压缩处理。
  5. 输入以单独一行的一个数字0 00表示结束,该0 00不参与输出。

需要注意的是,本题解压缩的输入文件实际上是一个压缩后的文件,其中包含了数字(表示单词在列表中的位置)和原始的非字母字符。我们需要根据这些数字和保留的单词信息,还原出原始的未压缩文本。

例如,在样例输入中:

Dear Sally, Please, please do it- - 1 would 4 Mary very, 1 much. And 4 6 8 everything in 5's power to make 14 pay off for you. Thank 2 18 18- - 0

我们需要正确解析其中的数字,将其替换为对应的单词,并更新单词列表的顺序。

解题思路

核心数据结构

由于单词需要频繁进行“移动到列表最前面”的操作,并且需要根据位置快速访问单词,我们可以选择list \texttt{list}list(双向链表)作为存储单词列表的数据结构。list \texttt{list}list支持O ( 1 ) O(1)O(1)时间在头部插入元素,也支持在任意位置删除元素(通过迭代器),非常适合本题的需求。

算法步骤

  1. 初始化一个空的list<string> words \texttt{list<string> words}list<string> words,用于存储已经出现过的单词,最新出现的单词放在链表头部。
  2. 逐行读入输入,直到遇到单独的一行"0"为止。
  3. 对于每一行文本,逐个字符处理:
    • 如果当前字符是数字:
      • 连续读取数字字符,组成一个完整的数字字符串。
      • 将该数字转换为整数n nn
      • words \texttt{words}words链表中找到第n nn个单词(注意位置从1 11开始)。
      • 将该单词输出到结果中。
      • 从链表中删除该单词。
      • 将该单词插入到链表的最前面(因为单词被再次使用,需要移动到列表头部)。
    • 如果当前字符是字母:
      • 连续读取字母字符,组成一个完整的单词。
      • 将该单词输出到结果中。
      • 将该单词插入到链表的最前面(因为是第一次出现,或者即使之前出现过但根据规则,这里实际上也是第一次出现的情况,因为压缩文件中如果是重复出现的单词,会用数字代替,不会出现字母序列)。
      • 注意:根据压缩规则,输入中的单词都是第一次出现的情况,因为在压缩过程中,只有第一次出现的单词才会被原样保留,重复的单词已经被替换为数字。所以这里我们不需要检查单词是否已经存在于链表中,直接插入即可。
    • 如果当前字符既不是数字也不是字母:
      • 直接将该字符输出到结果中。
  4. 每处理完一行,输出一个换行符。

关键细节

  • 单词的定义:单词是连续的字母序列(大小写敏感),"abc""Abc"被视为不同的单词。因此我们直接使用字符串比较即可,不需要额外处理大小写。
  • 数字的解析:数字可能不止一位,需要连续读取。例如样例中的18是一个完整的数字,表示列表中的第18 1818个单词。
  • 边界情况:当数字对应的单词被取出后,原位置被删除,链表的长度减1 11。然后将该单词插入头部,链表长度又恢复为原长度。列表中的单词顺序会随着每次“使用”而动态变化。
  • 输入终止:遇到单独一行的"0"时停止处理,"0"本身不输出。

复杂度分析

设原始文件中的单词总数为N NN,输入文件中的字符总数为M MM。每个单词插入头部是O ( 1 ) O(1)O(1)时间,根据位置查找单词需要O ( N ) O(N)O(N)时间(因为list \texttt{list}list不支持随机访问,需要通过迭代器移动)。最坏情况下,总时间复杂度为O ( N × M ) O(N \times M)O(N×M),但由于本题没有给出明确的上限,且数据规模通常较小,该做法可以通过。如果需要优化,可以使用vector \texttt{vector}vector配合哈希表记录位置,但list \texttt{list}list的实现简洁且满足题目要求。

代码实现

// Uncompress// UVa ID: 245// Verdict: Accepted// Submission Date: 2016-05-12// UVa Run Time: 0.060s//// 版权所有(C)2016,邱秋。metaphysis # yeah dot net#include<bits/stdc++.h>usingnamespacestd;intmain(intargc,char*argv[]){cin.tie(0);cout.sync_with_stdio(false);string line;list<string>words;// 存储单词列表,头部为最近使用的单词// 逐行读入,直到遇到单独的 "0"while(getline(cin,line),line!="0"){// 遍历当前行的每一个字符for(inti=0;i<line.length();i++){// 情况1:遇到数字,表示要解压缩为一个之前出现过的单词if(isdigit(line[i])){string number;number+=line[i++];// 读取第一个数字字符// 继续读取连续的数字字符while(i<line.length()&&isdigit(line[i]))number+=line[i++];// 将数字字符串转换为整数,得到单词在列表中的位置(从1开始)autoit=words.begin();advance(it,stoi(number)-1);// 移动到第 number 个单词// 取出该单词string word=*it;words.erase(it);// 从原位置删除// 输出该单词(解压缩结果)cout<<word;// 将该单词移动到列表头部words.insert(words.begin(),word);i--;// 因为外层循环会自增,这里回退一位}// 情况2:遇到字母,表示这是一个第一次出现的单词elseif(isalpha(line[i])){string word;word+=line[i++];// 读取第一个字母字符// 继续读取连续的字母字符while(i<line.length()&&isalpha(line[i]))word+=line[i++];// 将单词插入列表头部(表示最近使用)words.insert(words.begin(),word);// 直接输出该单词cout<<word;i--;// 回退一位}// 情况3:其他字符(标点、空格等),直接原样输出elsecout<<line[i];}// 每行处理完毕,输出换行符cout<<"\n";}return0;}

总结

本题通过模拟压缩过程中的单词列表维护来实现解压缩,核心在于正确识别输入中的数字和字母序列,并利用list \texttt{list}list高效地完成单词的查询、删除和插入操作。理解压缩与解压缩的对称性是解决本题的关键,即:压缩时第一次出现的单词保留原词并加入列表头部,重复出现的单词用列表位置编号代替;解压缩时遇到数字就去列表中查找对应位置的单词并输出,同时更新列表顺序。

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

今年网卡公司排名前十TOP榜:怎么选不花冤枉钱

不同预算选网卡公司的核心侧重点不同预算选网卡公司的核心侧重点差异十分明显。10万以上的中高端定制需求&#xff0c;核心要考察服务商的定制化能力、垂直行业适配经验、全流程技术服务能力&#xff0c;这类需求通常对应AI、超算、航空航天等对网络性能要求极高的场景&#xf…

作者头像 李华
网站建设 2026/5/21 0:26:15

别只当普通Office用!挖掘WPS教育考试版里那些被忽略的‘学习神器’

解锁WPS教育考试版的隐藏技能&#xff1a;从工具到学习伙伴的进阶指南 在备考的漫长征途中&#xff0c;我们常常陷入"工具只是工具"的思维定式。WPS教育考试版远不止是一个文档编辑器&#xff0c;它更像是一位24小时待命的学习助手&#xff0c;只是大多数人从未真正…

作者头像 李华
网站建设 2026/5/21 0:20:06

Taotoken API密钥管理与访问控制功能初体验

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 Taotoken API密钥管理与访问控制功能初体验 1. 引言 在将大模型能力集成到实际应用或团队协作流程中时&#xff0c;API密钥的管理…

作者头像 李华
网站建设 2026/5/21 0:19:57

毕业设计:基于springboot宠物领养系统的设计与实现(源码)

第4章 系统设计系统的设计一切都是为了用户的使用&#xff0c;虽然用户使用过程中可能只是面对着浏览器进行各种操作&#xff0c;但是不代表着系统对于用户在浏览器上的操作不进行处理&#xff0c;所以说&#xff0c;设计一个系统需要考虑到方方面面。4.1 功能结构设计图4.1即为…

作者头像 李华