문제 링크
https://www.acmicpc.net/problem/31024
문제
파일 시스템 명령어와 쿼리가 주어질 때, 각 쿼리가 요청하는 파일의 내용을 출력해야 한다. 만약 쿼리가 유효하지 않으면(예: 경로가 존재하지 않는 경우) invalid! 를 출력해야 한다.
다음 명령어들을 지원해야 한다.
지원 명령어
echo "<content>" > <path>
<path>파일에<content>를 쓴다.- 만약
<path>가 이미 존재한다면, 그것은 파일이어야 하며 내용은 덮어쓰인다. - 경로가 존재하지 않는다면, 부모 디렉터리는 반드시 존재해야 하며, 이 경우 파일이 새로 생성된다.
<content>는 ASCII 숫자, 문자,*,?,<,>, 그리고 공백만을 포함한다.
cp <source> <destination>
<source>파일을<destination>파일 또는 디렉터리로 복사한다.- 만약
<destination>이 이미 존재하는 디렉터리라면, 파일은<destination>디렉터리 안으로 복사되며, 파일명은<source>경로의 마지막 부분이 된다. - 그렇지 않다면,
<destination>이 새로운 파일명이 되며, 이 경우<destination>의 부모 디렉터리는 반드시 존재해야 한다. - 새 파일은 기존의 내용을 덮어쓴다.
mv <source> <destination>
- 파일 또는 디렉터리
<source>를<destination>파일 또는 디렉터리로 이동시킨다. cp와 유사하게,<destination>이 이미 존재하는 디렉터리라면, 소스 파일/디렉터리는<destination>디렉터리 안으로 이동한다. 이때 이름은<source>경로의 마지막 부분과 동일하다.- 그렇지 않다면,
<destination>이 새로운 파일명이 되며, 부모 디렉터리는 반드시 존재해야 한다. - 새 파일은 기존 내용을 덮어쓰고,
<source>는 삭제된다.
rm <path>
<path>경로의 파일을 삭제한다.
mkdir <path>
<path>경로에 디렉터리를 생성한다. 부모 디렉터리는 반드시 존재해야 한다.
rmdir <path>
<path>경로의 비어있는 디렉터리를 삭제한다.
※ 참고:
- 모든 파일 시스템 경로는 숫자, 문자, 또는
/만을 포함하며, 길이는 31자 또는 7개의 경로 구성 요소를 초과하지 않는다. - 경로 구성 요소는
/로 구분된다. - 입력으로 주어지는 모든 명령어는 유효하며, 위에서 명시된 경우를 제외하고는 존재하지 않거나 유효하지 않은 경로를 참조하지 않는다.
- 모든 명령어는 1024자 미만이다.
입력
- 첫 번째 줄에 테스트 케이스의 수를 나타내는
T(0 < T < 100)가 주어진다. - 다음 줄에 해당 테스트 케이스의 명령어 수를 나타내는
C(0 < C < 100)가 주어진다. - 이어지는
C개의 줄에 파일 시스템을 구성하는 명령어가 주어진다. - 파일 시스템이 시작되는 폴더는 무시해도 된다. 즉, 현재 디렉터리(
./)로 가정할 수 있다. - 다음 줄에 내용을 출력해야 할 파일명의 수를 나타내는
Q(0 < Q < 20)가 주어진다. - 이어지는
Q개의 줄에 내용을 출력할 파일명 (또는myfolder/myfile과 같은 경로 및 파일명)이 주어진다.
출력
- 쿼리가 요청하는 파일의 내용을 출력하거나, 파일이 존재하지 않으면 "invalid!"를 출력한다.
- 각 테스트 케이스가 끝난 후에는 빈 줄을 하나 출력한다.
코드
더보기
from collections import deque
from re import findall
def split_str(s):
items = findall(r'"[^"]+"|\S+', s)
result = []
for item in items:
if item.startswith('"') and item.endswith('"'):
result.append(item[1:-1])
else:
result.append(item)
return result
class File:
def __init__(self, name, content, directory=None):
self.name = name
self.content = content
self.directory = directory
def update_content(self, content):
self.content = content
class Folder:
def __init__(self, name, parent=None):
self.name = name
self.parent = parent
self.child = dict()
self.files = dict()
def add_child(self, child):
self.child[child.name] = child
child.parent = self
def remove_child(self, child):
self.child.pop(child.name)
child.parent = None
def add_file(self, file):
self.files[file.name] = file
file.directory = self
def remove_file(self, file):
self.files.pop(file.name)
file.directory = None
T = int(input())
for t in range(T):
root = Folder('')
c = int(input())
for _ in range(c):
cmd = split_str(input())
if cmd[0] == "echo":
content = cmd[1]
path = deque(cmd[-1].split('/'))
cur = root
while len(path) > 1:
cur = cur.child[path.popleft()]
if path[0] in cur.files:
cur.files[path[0]].update_content(content)
else:
new_file = File(path[0], content)
cur.add_file(new_file)
elif cmd[0] == "cp":
s_path = deque(cmd[1].split('/'))
d_path = deque(cmd[2].split('/'))
cur = root
while len(s_path) > 1:
cur = cur.child[s_path.popleft()]
target = cur.files[s_path[0]]
cur = root
while len(d_path) > 1:
cur = cur.child[d_path.popleft()]
if d_path[0] in cur.child: # destination is a directory
cur = cur.child[d_path[0]]
new_file = File(target.name, target.content)
else: # destination is a new filename
new_file = File(d_path[0], target.content)
cur.add_file(new_file)
elif cmd[0] == "mv":
s_path = deque(cmd[1].split('/'))
d_path = deque(cmd[2].split('/'))
cur = root
while len(s_path) > 1:
cur = cur.child[s_path.popleft()]
is_file = True
if s_path[0] in cur.files:
target = cur.files[s_path[0]]
else:
target = cur.child[s_path[0]]
is_file = False
cur = root
while len(d_path) > 1:
cur = cur.child[d_path.popleft()]
if d_path[0] in cur.child: # destination is a directory
cur = cur.child[d_path[0]]
if is_file:
new_file = File(target.name, target.content)
cur.add_file(new_file)
target.directory.remove_file(target)
else:
target.parent.remove_child(target)
cur.add_child(target)
else: # destination is a new filename
new_file = File(d_path[0], target.content)
cur.add_file(new_file)
target.directory.remove_file(target)
elif cmd[0] == "rm":
paths = deque(cmd[1].split('/'))
cur = root
while len(paths) > 1:
cur = cur.child[paths.popleft()]
cur.remove_file(cur.files[paths[0]])
elif cmd[0] == "mkdir":
paths = deque(cmd[1].split('/'))
cur = root
while len(paths) > 1:
cur = cur.child[paths.popleft()]
new_child = Folder(paths[0])
cur.add_child(new_child)
elif cmd[0] == "rmdir":
paths = deque(cmd[1].split('/'))
cur = root
while len(paths) > 1:
cur = cur.child[paths.popleft()]
cur.remove_child(cur.child[paths[0]])
q = int(input())
res = list()
is_error = False
for _ in range(q):
cmd = deque(input().split('/'))
try:
cur = root
while len(cmd) > 1:
cur = cur.child[cmd.popleft()]
res.append(cur.files[cmd[0]].content)
except:
is_error = True
break
if is_error:
print("invalid!")
else:
for r in res:
print(r)
if t != T-1:
print()
'PS > 백준' 카테고리의 다른 글
| [백준] (2263) 트리의 순회 [Python] (0) | 2025.11.03 |
|---|---|
| [백준] (2644) 촌수계산 [C] [C++] (0) | 2025.10.27 |
| [백준] (1194) 달이 차오른다, 가자. [Python] (0) | 2025.10.25 |
| [백준] (34560) 브레인롯 챔피언십 [Python] (0) | 2025.10.05 |
| [백준] (23059) 리그 오브 레게노 [Python] (0) | 2025.10.03 |