Untitled
unknown
c_cpp
a year ago
8.0 kB
12
Indexable
struct User { int capacity; int used; User(){} User(int capacity) : capacity(capacity), used(0) {} bool canAddFile(int fileSize) { return used + fileSize <= capacity; } void addFile(int fileSize) { used += fileSize; } void removeFile(int fileSize) { used -= fileSize; } int remainingCapacity() { return capacity - used; } }; struct CloudStorage { std::unordered_map<std::string, int> files; // File name to size mapping std::unordered_map<std::string, std::string> fileOwners; // File name to owner mapping std::unordered_map<std::string, User> users; // User ID to User object mapping std::map<int, std::set<std::string>, std::greater<int>> sizeToFileNames; // Size to file names mapping std::unordered_map<std::string, std::vector<std::pair<std::string, int>>> backups; CloudStorage() { // Adding an admin user with unlimited capacity users["admin"] = User(INT_MAX); } std::string addUser(const std::string& userId, int capacity) { if (users.find(userId) != users.end()) { return "false"; } users[userId] = User(capacity); //cout << users[userId].capacity << '\n'; return "true"; } std::string addFileBy(const std::string& userId, const std::string& fileName, int size) { if (files.find(fileName) != files.end() || users.find(userId) == users.end() || !users[userId].canAddFile(size)) { return ""; } files[fileName] = size; fileOwners[fileName] = userId; sizeToFileNames[size].insert(fileName); users[userId].addFile(size); cout << users[userId].capacity << '\n'; return std::to_string(users[userId].remainingCapacity()); } std::string mergeUsers(const std::string& userId1, const std::string& userId2) { if (userId1 == userId2 || users.find(userId1) == users.end() || users.find(userId2) == users.end()) { return ""; } users[userId1].capacity += users[userId2].capacity; for (const auto& [fileName, size] : files) { if (fileOwners[fileName] == userId2) { fileOwners[fileName] = userId1; users[userId1].addFile(size); users[userId2].removeFile(size); } } int remainingCapacity = users[userId1].remainingCapacity(); users.erase(userId2); return std::to_string(remainingCapacity); } std::string addFile(const std::string& name, int size) { if (files.find(name) != files.end()) { return "false"; } files[name] = size; fileOwners[name] = "admin"; // Associate the file with the admin user sizeToFileNames[size].insert(name); // No need to update the admin's used capacity since it's unlimited return "true"; } std::string getFileSize(const std::string& name) { auto it = files.find(name); if (it != files.end()) { return std::to_string(it->second); } return ""; } std::string deleteFile(const std::string& name) { auto it = files.find(name); if (it != files.end()) { int fileSize = it->second; std::string size = std::to_string(fileSize); sizeToFileNames[fileSize].erase(name); if (sizeToFileNames[fileSize].empty()) { sizeToFileNames.erase(fileSize); } // Find the owner of the file and update their used storage auto ownerIt = fileOwners.find(name); if (ownerIt != fileOwners.end()) { std::string ownerId = ownerIt->second; if (users.find(ownerId) != users.end()) { users[ownerId].removeFile(fileSize); } fileOwners.erase(ownerIt); } files.erase(it); return size; } return ""; } std::string getNLargestWithPrefix(const std::string& prefix, int n) { std::vector<std::pair<std::string, int>> matchingFiles; for (const auto& [size, names] : sizeToFileNames) { for (const auto& name : names) { if (name.substr(0, prefix.length()) == prefix) { matchingFiles.emplace_back(name, size); if (matchingFiles.size() == n) break; } } if (matchingFiles.size() == n) break; } std::sort(matchingFiles.begin(), matchingFiles.end(), [](const auto& a, const auto& b) { return a.second == b.second ? a.first < b.first : a.second > b.second; }); std::string result; for (const auto& [name, size] : matchingFiles) { if (!result.empty()) result += ", "; result += name + "(" + std::to_string(size) + ")"; } return result; } std::string backupUser(const std::string& userId) { if (users.find(userId) == users.end()) { return ""; // User does not exist } std::vector<std::pair<std::string, int>>& userBackup = backups[userId]; userBackup.clear(); // Clear existing backup for (const auto& [fileName, owner] : fileOwners) { if (owner == userId) { userBackup.emplace_back(fileName, files[fileName]); } } return std::to_string(userBackup.size()); } // RESTORE_USER implementation std::string restoreUser(const std::string& userId) { if (users.find(userId) == users.end()) { return ""; // User does not exist } // First, delete all current files owned by the user std::vector<std::string> filesToDelete; for (const auto& [fileName, owner] : fileOwners) { if (owner == userId) { filesToDelete.push_back(fileName); } } for (const auto& fileName : filesToDelete) { deleteFile(fileName); } // Now, proceed with the restoration from the backup if (backups.find(userId) == backups.end()) { return "0"; // No backup exists, so nothing is restored } int restoredFilesCount = 0; for (const auto& [fileName, size] : backups[userId]) { if (files.find(fileName) == files.end()) { // Restore file if it does not exist files[fileName] = size; fileOwners[fileName] = userId; sizeToFileNames[size].insert(fileName); users[userId].addFile(size); restoredFilesCount++; } // If file with same name exists, it's ignored } return std::to_string(restoredFilesCount); } }; vector<string> solution(vector<vector<string>> queries) { CloudStorage storage; vector<string>ans; for(auto q: queries){ auto op = q[0]; if(op == "ADD_FILE"){ ans.push_back(storage.addFile(q[1], stoi(q[2]))); } else if(op == "GET_FILE_SIZE"){ ans.push_back(storage.getFileSize(q[1])); } else if(op == "GET_N_LARGEST"){ ans.push_back(storage.getNLargestWithPrefix(q[1], stoi(q[2]))); } else if(op == "ADD_USER"){ ans.push_back(storage.addUser(q[1], stoi(q[2]))); } else if(op == "ADD_FILE_BY"){ ans.push_back(storage.addFileBy(q[1], q[2], stoi(q[3]))); } else if(op == "MERGE_USER"){ ans.push_back(storage.mergeUsers(q[1], q[2])); } else if(op == "BACKUP_USER"){ ans.push_back(storage.backupUser(q[1])); } else if(op == "RESTORE_USER") ans.push_back(storage.restoreUser(q[1])); else{ ans.push_back(storage.deleteFile(q[1])); } } return ans; }
Editor is loading...
Leave a Comment