简体   繁体   English

映射两个键值

[英]Map with two key values

I have an assignment where I need to go through all the files in a folder. 我有一个任务,我需要浏览文件夹中的所有文件。 For each file I need to know each unique file extension, how many files for each unique file extension, and the total size for each unique file extension. 对于每个文件,我需要知道每个唯一的文件扩展名,每个唯一文件扩展名的文件数以及每个唯一文件扩展名的总大小。 I have to be able to sort through this using either the file extension or the total size of the file extension. 我必须能够使用文件扩展名或文件扩展名的总大小对此进行排序。 The first thing I thought of using was a map. 我想到的第一件事是地图。 This will keep track of each unique file extension and the amount of times that file extension was found. 这将跟踪每个唯一的文件扩展名和找到文件扩展名的次数。 How do I now associate the total size of the file extension to my map? 我现在如何将文件扩展名的总大小与我的地图相关联? So for example I need the output to be something like this: 所以例如我需要输出是这样的:

Using file extension for sort .cpp : 1 : 3400 .exe : 3 : 3455600 .mp4 : 25 : 200000404 使用文件扩展名排序.cpp:1:3400 .exe:3:3455600 .mp4:25:200000404

Using total file extension size for sort .mp4 : 25 : 200000404 .exe : 3 : 3455600 .cpp : 1 : 3400 使用文件扩展名大小排序.mp4:25:200000404 .exe:3:3455600 .cpp:1:3400

Here is the code I have after some editing: 这是我编辑后的代码:

    #include <iostream>
    #include <filesystem>
    #include <map>

    using namespace std;
    using namespace std::tr2::sys;

    class fileInfo {
    public:
        int fileCount;
        long long fileSize;
    };

    void scan(path f)
    {
        map<string, fileInfo> fileMap;
        cout << "Scanning = " << system_complete(f) << endl;
        directory_iterator d(f);
        directory_iterator e;
        for( ; d != e; ++d)
        {
            path p = d->path();
            cout << "\nExtension is: " << extension(p) << "\tFile size is: " << file_size(p) << endl;
            fileMap[extension(p)].fileCount ++;
            fileMap[extension(p)].fileSize += file_size(p);
        }

        for (map<string, fileInfo>::iterator it = fileMap.begin(); it != fileMap.end(); ++it)
        {
             cout << it->first << " : " << it->second.fileCount << " : " << it->second.fileSize << endl;
        }
    }

    int main(int argc, char* argv[] )
    {
        path folder = "..";

        scan(folder);

        return 0;
     }

EDIT: So I have implemented the class fileInfo. 编辑:所以我已经实现了类fileInfo。 It is sort of working. 它有点工作。 But I am having a problem with the file_size. 但是我遇到了file_size的问题。 After the first run through the loop, it correctly returns the file_size, but for every other run through the loop file_size is returning 0. 在第一次运行循环之后,它正确返回file_size,但是对于每个其他运行循环,file_size返回0。

You can create one map: 您可以创建一个地图:

 map<string, vector<int> > fileExtToSizeMap;

Basically, for each file extension in string format, if the current file is associated with that extension, put the size of the file into the vector vector<int> . 基本上,对于string格式的每个文件扩展名,如果当前文件与该扩展名相关联,请将文件的大小放入向量vector<int> After you finished scanning the directory, the size of that vector will tell you how many files are associated with the file extension and the sum of the vector will tell you the total size for each unique file extension . 扫描完目录后,该向量的大小将告诉您how many files are associated with the file extension数量,向量总和将告诉您the total size for each unique file extension You two major questions are then answered by this data structure. 然后,您可以通过此数据结构回答两个主要问题。

I would create a data structure eg ExtensionStat like this: 我会创建一个数据结构,例如ExtensionStat如下所示:

struct ExtensionStat {
  int totalFile;
  int totalSize;
};

And have a map from extension name into the stat 并有一个从扩展名到地图的地图

map<string, ExtensionStat> extMap;

Then you just iterate contents of your folder collecting the statistics into extMap . 然后,您只需将收集统计信息的文件夹内容迭代到extMap Keep in mind you don't need to use struct, you can use class too. 请记住,您不需要使用struct,也可以使用class。 Also you can choose the map to be map<string, ExtensionStat*> extMap; 您也可以选择要map<string, ExtensionStat*> extMap; if you'd like to avoid full value copying 如果你想避免全价值复制

You could also use a multi-map 您还可以使用多地图

map<string, size_t> fileExtSizeMap;

Simple add a new entry for every file encountered. 简单地为遇到的每个文件添加一个新条目。

std::lower_bound and std::upperbound can be used to search this structure. std :: lower_bound和std :: upperbound可用于搜索此结构。 Use std::distance on resulting iterators to get a file count. 在生成的迭代器上使用std :: distance来获取文件计数。

Or simply iterate through the complete map incrementing a counter as you go. 或者只是遍历完整的地图,随时增加一个计数器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM