2017-12-19 9 views
1

私は、txtファイルからファイル名を取り出し、それらを数えて上位10のリストを作るC++プロジェクトを作成しようとしています。入力の小片を以下に示した:大きなデータをtxtから取り出してソートする

local - - [24/Oct/1994:13:41:41 -0600] "GET index.html HTTP/1.0" 200 150 
local - - [24/Oct/1994:13:41:41 -0600] "GET 1.gif HTTP/1.0" 200 1210 
local - - [24/Oct/1994:13:43:13 -0600] "GET index.html HTTP/``1.0" 200 3185 
local - - [24/Oct/1994:13:43:14 -0600] "GET 2.gif HTTP/1.0" 200 2555   
local - - [24/Oct/1994:13:43:15 -0600] "GET 3.gif HTTP/1.0" 200 36403 
local - - [24/Oct/1994:13:43:17 -0600] "GET 4.gif HTTP/1.0" 200 441  
local - - [24/Oct/1994:13:46:45 -0600] "GET index.html HTTP/1.0" 200 31853 

を私がやろうとしているコードは以下の通りです:

#include <iostream> 
#include <fstream> 
#include <sstream> 
#include <unordered_map> 
#include <vector> 
#include <iterator> 
#include <algorithm> 
#include <functional> 


std::string get_file_name(const std::string& s) { 
    std::size_t first = s.find_first_of("\""); 
    std::size_t last = s.find_last_of("\""); 

    std::string request = s.substr(first, first - last); 

    std::size_t file_begin = request.find_first_of(' '); 
    std::string truncated_request = request.substr(++file_begin); 

    std::size_t file_end = truncated_request.find(' '); 
    std::string file_name = truncated_request.substr(0, file_end); 

    return file_name; 
} 



int main() { 

    std::ifstream f_s("text.txt"); 
    std::string content; 
    std::unordered_map<std::string,long int> file_access_counts; 

    while (std::getline(f_s, content)) { 
     auto file_name = get_file_name(content); 
     auto item = file_access_counts.find(file_name); 

     if (item != file_access_counts.end()) { 
      ++file_access_counts.at(file_name); 
     } 
     else { 
      file_access_counts.insert(std::make_pair(file_name, 1)); 
     } 
    } 

    f_s.close(); 

    std::ofstream ofs; 
    ofs.open("all.txt", std::ofstream::out | std::ofstream::app); 

    for (auto& n : file_access_counts) 
     ofs << n.first << ", " << n.second << std::endl; 

    std::ifstream file("all.txt"); 
    std::vector<std::string> rows; 

    while (!file.eof()) 
    { 
     std::string line; 
     std::getline(file, line); 
     rows.push_back(line); 
    } 

    std::sort(rows.begin(), rows.end()); 
    std::vector<std::string>::iterator iterator = rows.begin(); 
    for (; iterator != rows.end(); ++iterator) 
     std::cout << *iterator << std::endl; 

    getchar(); 


    return 0; 
} 

私は実行すると、それは私にはファイル名を示しており、何度も繰り返すが、最高から最低までではなく、大規模なデータ(50000データなど)で動作するとは思われません。手伝って頂けますか? ありがとうございます。

+0

後に来ます。 " - 50000は大きくありません。また、https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong –

+0

[値を使用してstd :: mapをソートする]の可能な複製(https:// stackoverflow .com/questions/5056645/sorting-stdmap-using-value) – scohe001

+1

便利:https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong – Galik

答えて

0

all.txtの内容が読み込まれた後にソートされています。問題は、行の最後にカウントがあるため、名前の後のソートにのみ影響することです。

all.txt:ソート後

3.gif, 1 
index.html, 3 
1.gif, 1 
2.gif, 1 
4.gif, 1 

rowsはベクトル:

1.gif, 1 
2.gif, 1 
3.gif, 1 
4.gif, 1 
index.html, 3 

いずれかの値がall.txtに書き込まれている方法を変更、または並べ替えの前に数を解析します。

あなたが行の先頭に数を置く場合は、ゼロをパッドに必ずその3は、私はそれが(50000件のデータのような)大規模件のデータで動作することはないと思う」10