Remove Sub-Directories from a File System - GeeksforGeeks

08 Jun, 2021
Given an array of strings arr[] consisting of N unique directories in the form of strings, the task is to remove all the subdirectories and print the final array.
A directory S is a subdirectory if there exists any directory D such that S is the prefix of D.
Examples:
Input: arr[] = {“/a”, “/a/j”, “/c/d/e”, “/c/d”, “/b”}Output: { “/a”, “/c/d”, “/b”}Explanation: Directory “/a/j” is a subdirectory of directory “/a”, and “/c/d/e” is a subdirectory of directory “/c/d”.Therefore, remove both of them.
Input: arr[] = {“/a”, “/a/b”, “/a/b/c”, “/a/b/c/d”}Output: {“/a”}Explanation: All directories are subdirectories of “/a”
Naive Approach: The simplest approach is to traverse the array to check for each string, if there exists a string having it as the prefix and remove such strings from the array. 
Time Complexity: O(len * N2), where len is the length of the longest string in the array.Auxiliary Space: O(N)
Efficient Approach: The idea is to sort the given array and compare the current directory at position i with the previous directory at index (i -1). If arr[i – 1] is the prefix of arr[i] then remove arr[i]. After checking the whole array, print the remaining directories. Follow the below steps to solve the problem:
Sort all the directories alphabetically and initialize a vector res.
Insert the first directory into res.
Check each directory with the last valid directory i.e., last directory from res.
The directory is invalid(sub-directory) if it equals to some prefix of the previous valid directory. Else it is valid.
If the current directory is valid, then add it to res.
Print all the directories present in res after done traversing.
Below is the implementation of the above approach:
C++
Java
Python3
C#
// C++ program for the above approach #include <bits/stdc++.h>using namespace std; // Function to remove sub-directories// from the given lists dirvoid eraseSubdirectory(vector<string>& dir){    // Store final result    vector<string> res;     // Sort the given directories    sort(dir.begin(), dir.end());     // Insert 1st directory    res.push_back(dir[0]);     cout << "{" << dir[0] << ", ";     // Iterating in directory    for (int i = 1; i < dir.size(); i++) {         // Current directory        string curr = dir[i];         // Our previous valid directory        string prev = res.back();         // Find length of previous directory        int l = prev.length();         // If subdirectory is found        if (curr.length() > l && curr[l] == '/'            && prev == curr.substr(0, l))            continue;         // Else store it in result        // valid directory        res.push_back(curr);         cout << curr << ", ";    }     cout << "}\n";} // Driver Codeint main(){    // Given lists of directories dir[]    vector<string> dir        = { "/a", "/a/j", "/c/d/e",            "/c/d", "/b" };     // Function Call    eraseSubdirectory(dir);     return 0;}
// Java program for the above approachimport java.io.*;import java.util.*; class GFG{ // Function to remove sub-directories// from the given lists dirstatic void eraseSubdirectory(ArrayList<String> dir){         // Store final result    ArrayList<String> res = new ArrayList<String>();     // Sort the given directories    Collections.sort(dir);     // Insert 1st directory    res.add(dir.get(0));     System.out.print("{" + dir.get(0) + ", ");     // Iterating in directory    for(int i = 1; i < dir.size(); i++)    {                 // Current directory        String curr = dir.get(i);         // Our previous valid directory        String prev = res.get(res.size() - 1);         // Find length of previous directory        int l = prev.length();         // If subdirectory is found        if (curr.length() > l &&           curr.charAt(l) == '/' &&           prev.equals(curr.substring(0, l)))            continue;         // Else store it in result        // valid directory        res.add(curr);         System.out.print(curr + ", ");    }    System.out.print("}\n");} // Driver Codepublic static void main(String[] args){         // Given lists of directories dir[]    ArrayList<String> dir = new ArrayList<String>(Arrays.asList(            "/a", "/a/j", "/c/d/e", "/c/d", "/b"));     // Function Call    eraseSubdirectory(dir);}} // This code is contributed by akhilsaini
# Python3 program for the above approach # Function to remove sub-directories# from the given lists dirdef eraseSubdirectory(dir):         # Store final result    res = []     # Sort the given directories    dir.sort()     # Insert 1st directory    res.append(dir[0])     print("{", dir[0], end = ", ")     # Iterating in directory    for i in range(1, len(dir)):                 # Current directory        curr = dir[i]         # Our previous valid directory        prev = res[len(res) - 1]         # Find length of previous directory        l = len(prev)         # If subdirectory is found        if (len(curr) > l and           curr[l] == '/' and              prev == curr[:l]):            continue         # Else store it in result        # valid directory        res.append(curr)        print(curr, end = ", ")     print("}") # Driver Codeif __name__ == '__main__':     # Given lists of directories dir[]    dir = [ "/a", "/a/j", "/c/d/e", "/c/d", "/b" ]     # Function Call    eraseSubdirectory(dir) # This code is contributed by akhilsaini
// C# program for the above approachusing System;using System.Collections; class GFG{ // Function to remove sub-directories// from the given lists dirstatic void eraseSubdirectory(ArrayList dir){         // Store final result    ArrayList res = new ArrayList();     // Sort the given directories    dir.Sort();     // Insert 1st directory    res.Add(dir[0]);     Console.Write("{" + dir[0] + ", ");     // Iterating in directory    for(int i = 1; i < dir.Count; i++)    {                 // Current directory        string curr = (string)dir[i];         // Our previous valid directory        string prev = (string)res[(res.Count - 1)];         // Find length of previous directory        int l = prev.Length;         // If subdirectory is found        if (curr.Length > l && curr[l] == '/' &&            prev.Equals(curr.Substring(0, l)))            continue;         // Else store it in result        // valid directory        res.Add(curr);         Console.Write(curr + ", ");    }    Console.Write("}\n");} // Driver Codepublic static void Main(){         // Given lists of directories dir[]    ArrayList dir = new ArrayList(){ "/a", "/a/j",                                     "/c/d/e",                                     "/c/d", "/b" };     // Function Call    eraseSubdirectory(dir);}} // This code is contributed by akhilsaini
{/a, /b, /c/d, }
 
Time Complexity: O(N*log N)Auxiliary Space: O(N)
akhilsaini
simmytarika5
prefix
Arrays
Sorting
Strings
Arrays
Strings
Sorting
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Count pairs with given sum
Chocolate Distribution Problem
Window Sliding Technique
Reversal algorithm for array rotation
Next Greater Element