列表

详情


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

说明:

本题所有的文件操作都是在且仅在当前目录操作的,即保证touch、mkdir、rm和cd命令中不会包括/字符。
上述命令中echo、touch、mkdir、rm、cd命令有一个参数,ls、pwd、exit命令没有参数。
echo命令不输出引号

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

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;
		}
	}
}

上一题