-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.cc
123 lines (106 loc) · 3.84 KB
/
main.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include "FPGrowth.h"
#include <unistd.h>
#include <getopt.h>
#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <vector>
#include <functional>
#include <memory>
#include <boost/algorithm/string.hpp>
#define PROGNAME argv[0]
using std::string;
using std::vector;
static const option long_options[] = {
{"db", required_argument, nullptr, 'd'},
{"reserve", no_argument, nullptr, 'r'},
{"help", no_argument, nullptr, 'h'},
{nullptr, 0, nullptr, 0},
};
static void usage(const string &filename) {
std::cerr << filename << " [option]...\n"
<< " -d|--db [Path] Path of DB file.\n"
" -r|--reserve Reserve the shor pattern(default false)\n"
" -h|--help Print this help message.\n"
<< std::ends;
}
vector<string> splitString(const string &strInput, const string &delims) {
vector<string> vecSegment;
boost::split(vecSegment, strInput, boost::is_any_of(delims));
return vecSegment;
}
template<typename Key, typename Value, typename Function>
void insertOrUpdate(std::map<Key, Value> &dict, const Key &key, const Value &default_, const Function &f){
auto notFound = dict.end();
if ( dict.find(key) == notFound )
dict[key] = default_;
else
f(dict[key]);
}
int main(int argc, char *argv[]) {
if ( argc==1 ) {
usage(PROGNAME);
return 2;
}
int opt = 0;
int options_index = 0;
string str_pathDBFile;
bool reserveShortPattern=false;
while ( (opt=getopt_long(argc, argv, "d:hr", long_options, &options_index))!=EOF ) {
switch(opt) {
case 0: break;
case 'd': str_pathDBFile = optarg; break;
case 'r': reserveShortPattern = true; break;
case 'h':
case '?':
case ':': usage(PROGNAME); return 2;
}
}
if ( str_pathDBFile.empty() ){
usage(PROGNAME);
return 2;
}
std::ifstream fs;
fs.open(str_pathDBFile, std::fstream::in);
std::string line;
std::map<string, size_t> freqTable;
size_t line_no = 0;
// Scan database for creating frequent table
for ( ;std::getline(fs, line); ++line_no ) {
const vector<string> splited = splitString(line, ",");
const vector<string> areas = splitString(splited[4], ":");
const string &ip = splited[2];
const string &client = splited[3];
const string &country = areas[0];
const string &province = areas[1];
auto update_op = [](size_t &x) { ++x; };
if ( !ip.empty() ) insertOrUpdate(freqTable, ip, size_t(1), update_op);
if ( !client.empty() ) insertOrUpdate(freqTable, client, size_t(1), update_op);
if ( !country.empty() ) insertOrUpdate(freqTable, country, size_t(1), update_op);
if ( !province.empty() ) insertOrUpdate(freqTable, province, size_t(1), update_op);
//if ( !city.empty() ) insertOrUpdate(freqTable, city, 1, update_op);
}
NAMESPACE_ALPHALAB_NAME::FPGrowth fpGrowth(line_no, 0.09, 0.5);
fpGrowth.buildFPTable(freqTable);
fs.clear();
fs.seekg(0, fs.beg);
// Scan database for building FP tree
while ( std::getline(fs, line) ) {
const vector<string> splited = splitString(line, ",");
const vector<string> areas = splitString(splited[4], ":");
const string &ip = splited[2];
const string &client = splited[3];
const string &country = areas[0];
const string &province = areas[1];
fpGrowth.addRecord({ip, client, country, province});
}
fs.close();
std::vector<NAMESPACE_ALPHALAB_NAME::FPGrowth::TFreqPattern> patterns = fpGrowth.findAllFreqPattern(reserveShortPattern);
for ( const auto &pattern: patterns ) {
for ( const auto &item: pattern) {
std::cout << item << " ";
}
std::cout << std::endl;
}
}