NC14634. 简单的 Fish Shell
描述
Shell 是一个命令行解释器,它的作用是解释执行用户的命令,用户输入一条命令,Shell 就解释执行一条。这种方式称为交互式 (Interactive) 。
作为一条有理想的 ACMer 咸鱼,syf 想实现一个简易的操作系统,并通过一个 Shell 程序来进行简单的文件操作,并打算将其命名为 FSH(Fish Shell) AKA "Final Shell"。
你的任务是模拟 FSH 的一部分功能,要求支持以下命令:
echo "string"显示引号内的文本
ls列出当前目录下所有文件和目录,项目之间以两个空格符间隔
touch filename在当前目录下创建文件
mkdir directory在当前目录下创建目录
rm filename/directory删除当前目录下的文件或文件夹
cd dirname进入当前目录的一个子目录
pwd列出当前目录的完整路径
exit退出
其中文件名大小写敏感,目录可以看做是一种特殊的具有目录属性的文件。
规定文件名长度不超过64个字符,每个目录下最多可以存放1024个文件和目录(不包括子目录)。
初始时文件系统为空,仅有一个根目录"/",为用户的当前目录。
对于一段给出的命令,请进行相关操作来模拟 FSH 的输出,每行输出以回车符\n结束。
..表示上一层目录,特别地,本题中只有cd ..这种用法,表示进入上级目录。
输入描述
一段字符串命令,每行为一个命令,命令和参数之间用一个空格隔开,输入数据以exit命令结束。
输出描述
输出命令执行后的结果。
有输出的命令只有ls,pwd和echo三个,当前目录为空时ls输出为空,ls输出顺序和文件或目录创建顺序一致。
示例1
输入:
echo "acm" mkdir docs cd docs pwd touch test.docx ls rm test.docx ls pwd exit
输出:
acm /docs test.docx /docs
示例2
输入:
pwd echo "hello world" ls mkdir home mkdir bin mkdir lib ls cd home mkdir syf ls cd syf pwd touch acm.cpp touch test.cpp touch input.txt ls rm test.cpp ls pwd cd .. mkdir Linus_Torvalds mkdir Bill_Gates mkdir Nicolas_Zhaosi ls pwd exit
输出:
/ hello world home bin lib syf /home/syf acm.cpp test.cpp input.txt acm.cpp input.txt /home/syf syf Linus_Torvalds Bill_Gates Nicolas_Zhaosi /home
说明:
C++14(g++5.4) 解法, 执行用时: 4ms, 内存消耗: 600K, 提交时间: 2020-04-10 15:43:38
#include<bits/stdc++.h> using namespace std; map<int, pair<int, string> >par; void init() { pair<int, string>p(-1, ""); par[0] = p; } string Print(int k, int count1) { if(k == 0 && count1 == 0) return "/"; else if(k == 0 && count1 > 0) return ""; else return Print(par[k].first, count1+1) + '/' + par[k].second; } int main() { init(); string str; int k = 0; int count_ = 1; while(1) { getline(cin, str); int found = str.find(" "); int len = str.length(); string str1 = str.substr(0, found); string str2 = str.substr(found+1, len - found - 1); if(str1.compare("echo") == 0) { string str3 = str.substr(found+2, len - found - 3); cout << str3 << endl; } else if(str1.compare("exit") == 0) { break; } else if(str1.compare("ls") == 0) { int count1 = 0; for(map<int, pair<int, string> >::iterator it = par.begin(); it != par.end(); it++) { if(it->second.first == k) { if(count1 != 0) cout << " "; cout << it->second.second; count1++; } } //if(count1 !=0) cout << endl; } else if(str1.compare("touch") == 0) { pair<int, string>p(k, str2); par[count_] = p; count_++; } else if(str1.compare("mkdir") == 0) { pair<int, string>p(k, str2); par[count_] = p; count_++; } else if(str1.compare("rm") == 0) { int d; for(map<int, pair<int, string> >::iterator it = par.begin(); it != par.end(); it++) { if(it->second.second == str2) { d = it->first; par.erase(it); } } /* for(map<int, pair<int, string> >::iterator it = par.begin(); it != par.end(); it++) { if(it->first == d) { par.erase(it); } } */ } else if(str1.compare("cd") == 0) { if(str2.compare("..") == 0) { k = par[k].first; } else { pair<int, string>p1(k, str2); for(map<int, pair<int, string> >::iterator it = par.begin(); it != par.end(); it++) { if(it->second == p1) { k = it->first; } } } } else if(str1.compare("pwd") == 0) { string ans = Print(k, 0); cout << ans << endl; } } return 0; }
Java 解法, 执行用时: 41ms, 内存消耗: 10964K, 提交时间: 2022-04-20 11:11:12
import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class Main { public static void main(String[] arges){ Scanner in = new Scanner(System.in); boolean flag = true; Shell a = new Shell(); while(flag){ String s = in.nextLine(); String[] as = s.split(" "); switch (as[0]){ case "echo": String ns = s.substring(as[0].length() + 1); for(int i = 1;i < ns.length() - 1;i++){ System.out.print(ns.charAt(i)); } System.out.println(); break; case "touch": a.file.add(s.substring(as[0].length() + 1)); break; case "mkdir": Shell b = new Shell(); b.name = s.substring(as[0].length() + 1); a.mu.add(b); a.file.add(s.substring(as[0].length() + 1)); break; case "cd": if(s.substring(as[0].length() + 1).equals("..")){ Shell a1 = a.pre; a = a1; } else{ String n = a.path; Shell a1 = a; for(int i = 0;i < a.mu.size();i++){ if(a.mu.get(i).name.equals(s.substring(as[0].length() + 1))){ a = a.mu.get(i); a.pre = a1; } } if(n.equals("/")){ a.path = n + a.name; } else{ a.path = n + "/" + a.name; } } break; case "rm": a.file.remove(s.substring(as[0].length() + 1)); break; case "ls": if(a.file.size() != 0){ for(int i = 0;i < a.file.size();i++){ if(i == a.file.size() - 1){ System.out.print(a.file.get(i)); } else{ System.out.print(a.file.get(i)+" "); } } } System.out.println(); break; case "pwd": System.out.println(a.path); break; case "exit": flag = false; break; } } } } class Shell{ String name = ""; String path = "/"; List<String> file = new ArrayList<String>(1000); List<Shell> mu = new ArrayList<Shell>(1000); Shell pre; }
C++11(clang++ 3.9) 解法, 执行用时: 2ms, 内存消耗: 396K, 提交时间: 2020-10-13 15:53:48
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<math.h> struct dir{ char name[100]; int zdir[1025]; int zfile[1025]; int z; int super; }; dir d[1000]; char file[1030][100]; void put(int n){ for(int i=1;i<=d[n].z;i++){ if(d[n].zdir[i]!=0){ if(i!=1) printf(" %s",d[d[n].zdir[i]].name); else printf("%s",d[d[n].zdir[i]].name); } if(d[n].zfile[i]!=0){ if(i!=1) printf(" %s",file[d[n].zfile[i]]); else printf("%s",file[d[n].zfile[i]]); } } printf("\n"); } void del(char a[],int n){ for(int i=0;i<=d[n].z;i++){ if(d[n].zdir[i]!=0){ if(strcmp(d[d[n].zdir[i]].name,a)==0){ d[n].zdir[i]=0; break; } } if(d[n].zfile[i]!=0){ if(strcmp(file[d[n].zfile[i]],a)==0){ d[n].zfile[i]=0; break; } } } } int find(char a[],int n){ for(int i=0;i<=d[n].z;i++){ if(d[n].zdir[i]!=0){ if(strcmp(d[d[n].zdir[i]].name,a)==0) return d[n].zdir[i]; } } printf("don't find %s\n",a); return n; } void pput(int n){ if(d[n].super!=0) pput(d[n].super); printf("/%s",d[n].name); } int main(){ char a[1000]; char m[100]; char n[100]; int i=0; int di=0; int f=0; char ec[]="echo"; char ls[]="ls"; char to[]="touch"; char mk[]="mkdir"; char rm[]="rm"; char cd[]="cd"; char pw[]="pwd"; char ex[]="exit"; while(1){ scanf("%s",&m); if(strcmp(m,ec)==0){ gets(n); for(int j=2;j<strlen(n)-1;j++) printf("%c",n[j]); printf("\n"); }else if(strcmp(m,ls)==0){ put(i); }else if(strcmp(m,to)==0){ scanf("%s",&n); d[i].z++; f++; d[i].zfile[d[i].z]=f; strcpy(file[f],n); }else if(strcmp(m,mk)==0){ scanf("%s",&n); d[i].z++; di++; d[i].zdir[d[i].z]=di; strcpy(d[di].name,n); d[di].super=i; d[di].z=0; }else if(strcmp(m,rm)==0){ scanf("%s",&n); del(n,i); }else if(strcmp(m,cd)==0){ scanf("%s",n); if(strcmp(n,"..")==0) i=d[i].super; else i=find(n,i); }else if(strcmp(m,pw)==0){ pput(i); printf("\n"); }else if(strcmp(m,ex)==0){ break; } } }