代码求助
查看原帖
代码求助
379067
futz12楼主2021/11/15 21:01
#include <iostream>
#include <cstring>
#include <queue>
#include <vector>
#include <map>
using namespace std;

struct File;
struct Fold;

struct File
{
#define normal 1
#define uploading 2

    Fold *parent;

    int fileSize;
    int fileState;
};

struct Fold
{
#define normal 1
#define uploading 2

    int foldState;
    int foldSize;

    Fold *parent;

    map<string, File> fileMap;
    map<string, Fold> foldMap;
};

struct User
{
#define uploadUser 1
#define downloadUser 2
#define guest 3

#define scan 1
#define download 2
#define upload 3

    int userType;
    int userState;      //用户状态(用户正在执行的操作)
    Fold *userPosition; //用户当前所处的位置(即用户正在浏览的文件夹)
};

struct TaskFile
{
    string userName;
    File *file;
    int lastSize;
};

struct TaskFold
{
    string userName;
    Fold *fold;
    int lastSize;
};

struct FTP
{
    int maxUserNumber;
    int maxServerFlux;
    int maxUserFlux;

    Fold Root;
    map<string, User> userMap;

    vector<TaskFile> taskFile;
    vector<TaskFold> taskFold;

    bool connect(string userName, int State)
    {
        if (userMap.find(userName) == userMap.end())
        {
            if (userMap.size() >= maxUserNumber)
            {
                return false;
            }
            User user;
            user.userType = State;
            user.userState = scan;
            user.userPosition = &Root;
            userMap[userName] = user;
            return true;
        }
        else
        {
            return false;
        }
    }

    bool quit(string userName)
    {
        if (userMap.find(userName) != userMap.end())
        {
            userMap.erase(userName);
            vector<TaskFile> tmp;
            for (int i = 0; i < taskFile.size(); i++)
            {
                if (!(taskFile[i].userName == userName))
                    tmp.push_back(taskFile[i]);
            }
            taskFile = tmp;
            vector<TaskFold> tmp2;
            for (int i = 0; i < taskFold.size(); i++)
            {
                if (!(taskFold[i].userName == userName))
                    tmp2.push_back(taskFold[i]);
            }
            taskFold = tmp2;
            return true;
        }
        else
        {
            return false;
        }
    }

    bool cd(string userName, string foldName)
    {
        if (userMap.find(userName) == userMap.end())
        {
            return false;
        }
        if (userMap[userName].userPosition->foldMap.find(foldName) != userMap[userName].userPosition->foldMap.end())
        {
            if (userMap[userName].userPosition->foldMap[foldName].foldState == normal)
            {
                userMap[userName].userPosition = &userMap[userName].userPosition->foldMap[foldName];
                return true;
            }
            else
            {
                return false;
            }
        }
        else
        {
            return false;
        }
    }

    bool cd_back(string userName)
    {
        if (userMap.find(userName) == userMap.end())
        {
            return false;
        }
        if (userMap[userName].userPosition->parent != NULL)
        {
            userMap[userName].userPosition = userMap[userName].userPosition->parent;
            return true;
        }
        else
        {
            return false;
        }
    }

    bool startdownload(string userName, string fileName)
    {
        if (userMap.find(userName) == userMap.end())
        {
            return false;
        }
        if (userMap[userName].userType != downloadUser)
        {
            return false;
        }
        if (userMap[userName].userState != scan)
        {
            return false;
        }
        if (userMap[userName].userPosition->fileMap.find(fileName) == userMap[userName].userPosition->fileMap.end() && userMap[userName].userPosition->foldMap.find(fileName) == userMap[userName].userPosition->foldMap.end())
        {
            return false;
        }
        if (userMap[userName].userPosition->fileMap.find(fileName) != userMap[userName].userPosition->fileMap.end())
        {
            if (userMap[userName].userPosition->fileMap[fileName].fileState == normal)
            {
                TaskFile task;
                task.userName = userName;
                task.file = &userMap[userName].userPosition->fileMap[fileName];
                task.lastSize = userMap[userName].userPosition->fileMap[fileName].fileSize;
                taskFile.push_back(task);
                userMap[userName].userState = download;
                return true;
            }
            else
            {
                return false;
            }
        }
        if (userMap[userName].userPosition->foldMap.find(fileName) != userMap[userName].userPosition->foldMap.end())
        {
            if (userMap[userName].userPosition->foldMap[fileName].foldState == normal)
            {
                TaskFold task;
                task.userName = userName;
                task.fold = &userMap[userName].userPosition->foldMap[fileName];
                task.lastSize = userMap[userName].userPosition->foldMap[fileName].foldSize;
                taskFold.push_back(task);
                userMap[userName].userState = download;
                return true;
            }
            else
            {
                return false;
            }
        }
    }

    bool startupload(string userName, string fileName, int size)
    {
        if (userMap.find(userName) == userMap.end())
        {
            return false;
        }
        if (userMap[userName].userType != uploadUser)
        {
            return false;
        }
        if (userMap[userName].userState != scan)
        {
            return false;
        }
        if (size == 0) //Fold
        {
            if (userMap[userName].userPosition->foldMap.find(fileName) != userMap[userName].userPosition->foldMap.end())
            {
                return false;
            }
            else
            {
                Fold newFold;
                newFold.foldState = uploading;
                newFold.foldSize = 0;
                newFold.parent = userMap[userName].userPosition;

                userMap[userName].userPosition->foldMap[fileName] = newFold;

                return true;
            }
        }
        else
        {
            if (userMap[userName].userPosition->fileMap.find(fileName) != userMap[userName].userPosition->fileMap.end())
            {
                return false;
            }
            else
            {
                File newFile;
                newFile.fileSize = size;
                newFile.fileState = uploading;
                newFile.parent = userMap[userName].userPosition;

                userMap[userName].userPosition->fileMap[fileName] = newFile;

                TaskFile newtask;

                newtask.userName = userName;
                newtask.file = &userMap[userName].userPosition->fileMap[fileName];
                newtask.lastSize = size;

                taskFile.push_back(newtask);
                //更新父文件夹大小
                Fold *nowFold = userMap[userName].userPosition;
                while (nowFold != NULL)
                {
                    nowFold->foldSize += size;
                    nowFold->foldState = uploading;
                    nowFold = nowFold->parent;
                }
                userMap[userName].userState = upload;
                return true;
            }
        }
        return false;
    }
} Server;

inline void init()
{
    Server.Root.foldState = normal;
    Server.Root.foldSize = 0;
    Server.Root.parent = NULL;

    cin >> Server.maxUserNumber >> Server.maxServerFlux >> Server.maxUserFlux;

    Fold *nowfold = &Server.Root;

    while (nowfold != NULL)
    {
        string filename;
        cin >> filename;
        if (filename == "-")
        {
            for (auto &i : nowfold->foldMap)
            {
                nowfold->foldSize += i.second.foldSize;
            }
            for (auto &i : nowfold->fileMap)
            {
                nowfold->foldSize += i.second.fileSize;
            }
            nowfold = nowfold->parent;
        }
        else
        {
            int size;
            cin >> size;
            if (size == 0) //Fold
            {
                Fold newFold;
                newFold.foldState = normal;
                newFold.foldSize = 0;
                newFold.parent = nowfold;

                nowfold->foldMap[filename] = newFold;
                nowfold = &nowfold->foldMap[filename];
            }
            else //File
            {
                File newFile;
                newFile.fileSize = size;
                newFile.fileState = normal;
                newFile.parent = nowfold;

                nowfold->fileMap[filename] = newFile;
            }
        }
    }
    return;
}

void unlock_fold(Fold *nowfold)
{
    if (nowfold == NULL)
    {
        return;
    }
    for (auto &i : nowfold->foldMap)
    {
        if (i.second.foldState != normal)
        {
            return;
        }
    }
    for (auto &i : nowfold->fileMap)
    {
        if (i.second.fileState != normal)
        {
            return;
        }
    }
    nowfold->foldState = normal;
    //向上解锁
    unlock_fold(nowfold->parent);
}

int nowTime = 0;

inline void time_loop(int to)
{
    while (nowTime < to)
    {
        if (int(Server.taskFile.size() + Server.taskFold.size()) == 0) //没有任务
        {
            nowTime = to;
            return;
        }
        nowTime++;
        int singleflux = min(Server.maxServerFlux / int(Server.taskFile.size() + Server.taskFold.size()), Server.maxUserFlux);

        vector<TaskFile> Tmp;

        for (auto &i : Server.taskFile)
        {
            i.lastSize -= singleflux;
            if (i.lastSize <= 0)
            {
                i.file->fileState = normal;
                Server.userMap[i.userName].userState = scan;
                unlock_fold(i.file->parent);
            }
            else
                Tmp.push_back(i);
        }
        Server.taskFile = Tmp;

        vector<TaskFold> Tmp2;
        for (auto &i : Server.taskFold)
        {
            i.lastSize -= singleflux;
            if (i.lastSize <= 0)
            {
                i.fold->foldState = normal;
                Server.userMap[i.userName].userState = scan;
                unlock_fold(i.fold->parent);
            }
            else
                Tmp2.push_back(i);
        }
        Server.taskFold = Tmp2;
    }
}

inline void run()
{
    while (true)
    {
        int time;
        string operUser, opt;
        cin >> time >> operUser >> opt;
        time_loop(time);
        if (opt == "")
        {
            break;
        }
        if (opt == "connect")
        {
            int userType;
            cin >> userType;
            if (Server.connect(operUser, userType))
            {
                cout << "success" << endl;
            }
            else
            {
                cout << "unsuccess" << endl;
            }
        }
        else if (opt == "quit")
        {
            if (Server.quit(operUser))
            {
                cout << "success" << endl;
            }
            else
            {
                cout << "unsuccess" << endl;
            }
        }
        else if (opt == "cd")
        {
            string foldname;
            cin >> foldname;
            if (Server.cd(operUser, foldname))
            {
                cout << "success" << endl;
            }
            else
            {
                cout << "unsuccess" << endl;
            }
        }
        else if (opt == "cd..")
        {
            if (Server.cd_back(operUser))
            {
                cout << "success" << endl;
            }
            else
            {
                cout << "unsuccess" << endl;
            }
        }
        else if (opt == "download")
        {
            string optname;
            cin >> optname;
            if (Server.startdownload(operUser, optname))
            {
                cout << "success" << endl;
            }
            else
            {
                cout << "unsuccess" << endl;
            }
        }
        else if (opt == "upload")
        {
            string optname;
            int size;
            cin >> optname >> size;
            if (Server.startupload(operUser, optname, size))
            {
                cout << "success" << endl;
            }
            else
            {
                cout << "unsuccess" << endl;
            }
        }
    }
}
int main()
{
    init();
    run();
    return 0;
}
2021/11/15 21:01
加载中...