-
Notifications
You must be signed in to change notification settings - Fork 36
/
strtk_random_line.cpp
89 lines (70 loc) · 2.49 KB
/
strtk_random_line.cpp
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
/*
*****************************************************************
* String Toolkit Library *
* *
* Random Line Selection *
* Author: Arash Partow (2002-2020) *
* URL: http://www.partow.net/programming/strtk/index.html *
* *
* Copyright notice: *
* Free use of the String Toolkit Library is permitted under the *
* guidelines and in accordance with the most current version of *
* the MIT License. *
* http://www.opensource.org/licenses/MIT *
* *
*****************************************************************
*/
/*
Description: This is a solution to the problem of randomly selecting a line
from a text file in the most efficient way possible taking into
account time and space complexities, also ensuring that the
probability of the line selected is exactly 1/N where N is the
number of lines in the text file - It should be noted that the
lines can be of varying length.
*/
#include <cstddef>
#include <iostream>
#include <iterator>
#include <string>
#include <deque>
#include <ctime>
#include <boost/random.hpp>
//#include <random>
#include "strtk.hpp"
#ifndef strtk_enable_random
#error This example requires random
#endif
class random_line_selector
{
public:
random_line_selector(std::string& line, const std::size_t& seed = 0xA5A5A5A5)
: line_count_(1),
line_(line),
rng_(seed)
{}
inline void operator()(const std::string& s)
{
if (rng_() < (1.0 / line_count_))
line_ = s;
++line_count_;
}
private:
random_line_selector operator=(const random_line_selector&);
std::size_t line_count_; // should be long long
std::string& line_;
strtk::uniform_real_rng rng_;
};
int main(int argc, char* argv[])
{
if (2 != argc)
{
std::cout << "usage: strtk_random_line <file name>" << std::endl;
return 1;
}
std::string file_name = argv[1];
std::string line;
strtk::for_each_line(file_name,
random_line_selector(line,static_cast<std::size_t>(::time(0))));
std::cout << line << std::endl;
return 0;
}