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

UVa 282 Rename

题目描述

MS-DOS\texttt{MS-DOS}MS-DOSUnix\texttt{Unix}Unix系统中,都存在重命名文件的命令。MS-DOS\texttt{MS-DOS}MS-DOS中使用rename,而Unix\texttt{Unix}Unix中使用mv。两者的一个重要区别在于对通配符*的处理方式不同。

MS-DOS\texttt{MS-DOS}MS-DOS中,可以使用如下命令:

renameold* new*

这条命令会将所有以old开头的文件名中的old替换为new。然而在Unix\texttt{Unix}Unix中,mv命令并不支持这种通配符写法。

本题要求我们编写一个程序,将MS-DOS\texttt{MS-DOS}MS-DOS风格的rename命令转换为一系列Unix\texttt{Unix}Unix风格的mv命令。

输入格式

  • 每个数据集首先包含一个文件名列表,每行一个文件名,以单独一行的end结束。
  • 随后是一系列rename命令,每行格式为rename wildfrom wildto,其中wildfromwildto各包含恰好一个通配符*
  • 命令列表以单独一行的end结束。
  • 输入中不会出现重复的文件名。

输出格式

  • 对于每条rename命令,首先原样输出该命令。
  • 然后输出一系列mv命令,顺序与输入中文件名的出现顺序一致。
  • 每个数据集结束后输出一个空行。

特殊规则

  • 本题中的*可以匹配任意数量的任意可打印字符(没有MS-DOS\texttt{MS-DOS}MS-DOS888字符或点号.的限制)。
  • 大小写敏感(与Unix\texttt{Unix}Unix一致)。
  • 文件名长度限制为141414个字符。
  • 每条rename命令基于原始的文件名列表执行,而不是上一条命令的结果。

解题思路

问题本质

将一条形如rename A*B C*D的命令,转换为若干条mv命令。对于每个匹配A*B模式的文件名,需要将其转换为C*D模式。

这里的ABCD均为字符串(可能为空),*代表一个“通配符占位符”。匹配的规则是:文件名以A开头,以B结尾,中间的部分(即*匹配的内容)可以任意长度(包括空串)。

转换后的新文件名应当为:C+ 中间匹配的部分 +D

核心难点:如何匹配*所对应的子串

给定一个模式from(例如abFile*.c)和一个文件名(例如abFile001.c),我们需要找出*所匹配的具体内容。

模式分解

模式from中包含恰好一个*,可以将其分解为两部分:

  • 前缀:*之前的所有字符
  • 后缀:*之后的所有字符

例如:

  • abFile*.c→ 前缀abFile,后缀.c
  • ac*.c→ 前缀ac,后缀.c
  • *→ 前缀""(空串),后缀""(空串)
匹配规则

对于文件名filename,如果它能够匹配模式from,则必须满足:

  1. 前缀匹配:文件名开头部分必须完全等于from的前缀
  2. 后缀匹配:文件名结尾部分必须完全等于from的后缀
  3. 前缀和后缀不能重叠:前缀匹配的结尾位置必须严格小于后缀匹配的开始位置

匹配完成后,*所对应的内容就是文件名中位于前缀之后、后缀之前的子串。

例如:

  • 模式abFile*.c,文件名abFile001.c
    • 前缀abFile匹配前555个字符
    • 后缀.c匹配最后222个字符
    • 中间部分为001
特殊情况处理

需要考虑边界情况:

  • 前缀或后缀可能为空
  • *匹配的内容可以为空(例如a*匹配a,中间部分为空)
  • 文件名长度可能正好等于前缀长度 + 后缀长度,此时*匹配空串

算法步骤

  1. 读取文件名列表:将所有文件名存储到vector<string>中,直到遇到end

  2. 处理每条rename命令

    • 读取commandfromto
    • 输出原始命令
    • to中提取firstpart*之前的部分)和secondpart*之后的部分)
    • 遍历所有原始文件名,对每个文件名执行匹配和转换
  3. 匹配和转换

    • 使用两个指针分别从前往后和从后往前扫描
    • 前向扫描:比较fromfilename的字符,直到遇到*或不匹配
    • 后向扫描:比较fromfilename的末尾字符,直到遇到*或不匹配
    • 验证匹配条件:
      • 两个扫描都正确地在*位置停止
      • 前后扫描的区间不重叠(即前缀结束位置i−1i - 1i1必须小于后缀开始位置j+1j + 1j+1
    • 提取中间部分:filename[i..j]
    • 构造新文件名:firstpart + mid + secondpart
    • 输出mv oldname newname

正确性分析

这种双向扫描方法能够正确处理各种情况:

  • from*开头时,前缀为空,前向扫描立即遇到*
  • from*结尾时,后缀为空,后向扫描立即遇到*
  • 通过比较iiijjj的值可以检测出前缀和后缀是否重叠(即模式无法匹配的情况)

时间复杂度:O(N×M)O(N \times M)O(N×M),其中NNN是文件名数量,MMM是文件名平均长度。由于文件名长度不超过141414,这个复杂度完全可以接受。

代码实现

// Rename// UVa ID: 282// Verdict: Accepted// Submission Date: 2016-06-06// UVa Run Time: 0.120s//// 版权所有(C)2016,邱秋。metaphysis # yeah dot net#include<bits/stdc++.h>usingnamespacestd;string firstpart,secondpart,command,from,to;// 匹配并转换单个文件名voidmatch(string&filename){// 前向扫描:比较前缀inti=0;while(i<from.length()&&i<filename.length()&&from[i]==filename[i]&&from[i]!='*')i++;// 后向扫描:比较后缀intj=filename.length()-1,k=from.length()-1;while(j>=0&&k>=0&&filename[j]==from[k]&&from[k]!='*')j--,k--;// 验证匹配条件:// 1. 前向扫描必须在 '*' 处停止// 2. 后向扫描也必须在 '*' 处停止// 3. 前后扫描的区间不能重叠if(from[i]!='*'||from[k]!='*'||i>j+1)return;// 输出 mv 命令cout<<"mv "<<filename<<" ";// 输出新文件名:firstpart + 中间部分 + secondpartcout<<firstpart;for(intk=i;k<=j;k++)cout<<filename[k];cout<<secondpart<<endl;}intmain(){ios::sync_with_stdio(false);string line;vector<string>filenames;while(cin>>line){// 读取文件名列表if(line!="end")filenames.push_back(line);else{// 处理 rename 命令序列while(cin>>command,command!="end"){cin>>from>>to;// 输出原始命令cout<<command<<" "<<from<<" "<<to<<endl;// 从目标模式 to 中提取 firstpart 和 secondpart// firstpart: '*' 之前的部分firstpart.clear();secondpart.clear();for(inti=0;i<to.length()&&to[i]!='*';i++)firstpart+=to[i];// secondpart: '*' 之后的部分for(intj=to.length()-1;j>=0&&to[j]!='*';j--)secondpart.insert(secondpart.begin(),to[j]);// 对每个原始文件名进行匹配和转换for(inti=0;i<filenames.size();i++)match(filenames[i]);}// 每个数据集结束后输出空行cout<<endl;// 清空文件名列表,准备处理下一个数据集filenames.clear();}}return0;}

总结

本题的核心在于理解MS-DOS\texttt{MS-DOS}MS-DOS通配符*的匹配语义,并将其正确转换为Unix\texttt{Unix}Unixmv命令序列。通过将模式分解为前缀和后缀,并利用双向扫描确定*匹配的内容,可以简洁地解决问题。代码中需要注意边界条件处理,特别是当*出现在模式开头或结尾时的情况。

http://www.jsqmd.com/news/877479/

相关文章:

  • 利用 Taotoken 统一 API 简化多模型 A/B 测试的实验流程
  • 2026重庆市黄金回收行情实录,五家合规店铺口碑+免费上门 - 亦辰小黄鸭
  • 终极指南:如何免费获取Grammarly Premium高级Cookie的完整教程
  • 哔哩下载姬DownKyi终极指南:免费获取B站8K超高清视频的完整教程
  • 2026梧州市黄金回收行情实录,五家合规店铺口碑+免费上门 - 亦辰小黄鸭
  • 机器学习预测材料能带隙:从数据驱动到高通量筛选的实践指南
  • 家电维修清洗获客太难?2026全新推广引流获客,靠GEO优化告别低价内卷 - 一点学习库
  • 2026推荐:海口CMA甲醛检测治理及公共卫生检测报告排行榜(2026版) - 金诚回收
  • 2026舟山市黄金回收行情实录,五家合规店铺口碑+免费上门 - 亦辰小黄鸭
  • 2026推荐:淮北CMA甲醛检测治理公司及洁净室公共卫生检测报告排行榜(2026版) - 金诚回收
  • Taotoken用量看板如何帮助项目管理者精细化分析AI支出
  • 2026推荐:海南省CMA甲醛检测治理及公共卫生检测报告排行榜(2026版) - 金诚回收
  • 白城市2026最新黄金回收本地口碑商家榜:黄金首饰+白银+铂金+彩金回收门店及联系方式推荐 - 前途无量YY
  • 2026推荐:河源母婴除甲醛CMA甲醛检测治理公司推荐品牌排行榜 - 金诚回收
  • 5分钟掌握中国车牌生成器:为AI训练提供无限车牌数据
  • 2026推荐:嘉兴母婴除甲醛CMA甲醛检测治理公司多少钱怎么收费 - 金诚回收
  • 2026周口市黄金回收行情实录,五家合规店铺口碑+免费上门 - 亦辰小黄鸭
  • 2026珠海市黄金回收行情实录,五家合规店铺口碑+免费上门 - 亦辰小黄鸭
  • 毕业论文查重居然不花钱?揭秘书匠策AI这个免费神器的正确打开方式
  • 2026年必备四招精准降低AI率,搭配降AI率工具解决论文AI味超标一次过审 - 降AI实验室
  • 2026推荐:衡阳母婴除甲醛CMA甲醛检测治理公司多少钱怎么收费 - 金诚回收
  • 解锁你的音乐自由:qmc-decoder解密QQ音乐加密音频的终极指南
  • 对比直接使用厂商API体验Taotoken聚合调用的优势
  • 2026武汉市黄金回收行情实录,五家合规店铺口碑+免费上门 - 亦辰小黄鸭
  • 2026推荐:衡阳母婴除甲醛CMA甲醛检测治理公司哪家好权威机构 - 金诚回收
  • 白山市2026最新黄金回收本地口碑商家榜:黄金首饰+白银+铂金+彩金回收门店及联系方式推荐 - 前途无量YY
  • 2026河源正规贵金属奢侈品回收平台排名 金奢汇凭硬核官方认证领跑 - 小仙贝贝
  • 2026株洲市黄金回收行情实录,五家合规店铺口碑+免费上门 - 亦辰小黄鸭
  • 终极指南:3分钟在Windows上完成Dlib预编译包部署
  • OpenClaw 智能体工作流如何无缝对接 Taotoken 平台