Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cassert>
- #include <iostream>
- #include <list>
- #include <random>
- #include <string>
- #include <unordered_map>
- const size_t LIMIT = 5;
- const size_t LENGTH = 200;
- typedef std::unordered_map <std::string, size_t> TDistribution;
- TDistribution ReadModel() {
- TDistribution distribution;
- std::string line;
- std::string buffer;
- while (getline(std::cin, line)) {
- for (char c : line) {
- buffer += c;
- if (buffer.length() > LIMIT) {
- buffer = buffer.substr(buffer.length() - LIMIT);
- }
- if (buffer.length() == LIMIT) {
- ++distribution[buffer];
- }
- }
- }
- return distribution;
- }
- void PrintModel(const TDistribution &distribution) {
- for (const auto &item : distribution) {
- std::cout << item.first << ": " << item.second << std::endl;
- }
- }
- size_t Random(size_t lower, size_t upper) {
- static std::random_device device;
- static std::mt19937 generator(device());
- std::uniform_int_distribution<> distribution(lower, upper);
- return distribution(generator);
- }
- char PickNext(const TDistribution &distribution, const std::string &tail) {
- assert(tail.length() == LIMIT - 1);
- std::list <TDistribution::const_iterator> possibleEndings;
- size_t sum = 0;
- for (int c = 0; c < 256; ++c) {
- auto found = distribution.find(tail + static_cast <char> (c));
- if (found != distribution.end()) {
- possibleEndings.push_back(found);
- sum += found->second;
- }
- }
- if (sum == 0) {
- return 0;
- }
- size_t choice = Random(0, sum - 1);
- for (const auto &ending : possibleEndings) {
- if (choice < ending->second) {
- return ending->first.back();
- }
- choice -= ending->second;
- }
- const bool wrongRandomNumber = true;
- assert(!wrongRandomNumber);
- return 0;
- }
- std::string PickBegining(const TDistribution &distribution) {
- size_t sum = 0;
- for (const auto &item : distribution) {
- sum += item.second;
- }
- if (sum == 0) {
- return 0;
- }
- size_t choice = Random(0, sum - 1);
- for (const auto &item : distribution) {
- if (choice < item.second) {
- return item.first;
- }
- choice -= item.second;
- }
- const bool wrongRandomNumber = true;
- assert(!wrongRandomNumber);
- return "";
- }
- std::string GenerateText(const TDistribution &distribution, size_t length) {
- std::string text = PickBegining(distribution);
- while (text.length() < length) {
- char next = PickNext(distribution, text.substr(text.length() - LIMIT + 1));
- if (next == 0) {
- break;
- }
- text += next;
- }
- return text;
- }
- int main() {
- auto distribution = ReadModel();
- PrintModel(distribution);
- auto text = GenerateText(distribution, LENGTH);
- std::cout << text << std::endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement