Advertisement
Guest User

Untitled

a guest
Sep 19th, 2016
169
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.61 KB | None | 0 0
  1. #include <cassert>
  2. #include <iostream>
  3. #include <list>
  4. #include <random>
  5. #include <string>
  6. #include <unordered_map>
  7.  
  8. const size_t LIMIT = 5;
  9. const size_t LENGTH = 200;
  10. typedef std::unordered_map <std::string, size_t> TDistribution;
  11.  
  12. TDistribution ReadModel() {
  13.     TDistribution distribution;
  14.     std::string line;
  15.     std::string buffer;
  16.     while (getline(std::cin, line)) {
  17.         for (char c : line) {
  18.             buffer += c;
  19.             if (buffer.length() > LIMIT) {
  20.                 buffer = buffer.substr(buffer.length() - LIMIT);
  21.             }
  22.             if (buffer.length() == LIMIT) {
  23.                 ++distribution[buffer];
  24.             }
  25.         }
  26.     }
  27.     return distribution;
  28. }
  29.  
  30. void PrintModel(const TDistribution &distribution) {
  31.     for (const auto &item : distribution) {
  32.         std::cout << item.first << ": " << item.second << std::endl;
  33.     }
  34. }
  35.  
  36. size_t Random(size_t lower, size_t upper) {
  37.     static std::random_device device;
  38.     static std::mt19937 generator(device());
  39.     std::uniform_int_distribution<> distribution(lower, upper);
  40.     return distribution(generator);
  41. }
  42.  
  43. char PickNext(const TDistribution &distribution, const std::string &tail) {
  44.     assert(tail.length() == LIMIT - 1);
  45.     std::list <TDistribution::const_iterator> possibleEndings;
  46.     size_t sum = 0;
  47.     for (int c = 0; c < 256; ++c) {
  48.         auto found = distribution.find(tail + static_cast <char> (c));
  49.         if (found != distribution.end()) {
  50.             possibleEndings.push_back(found);
  51.             sum += found->second;
  52.         }
  53.     }
  54.     if (sum == 0) {
  55.         return 0;
  56.     }
  57.     size_t choice = Random(0, sum - 1);
  58.     for (const auto &ending : possibleEndings) {
  59.         if (choice < ending->second) {
  60.             return ending->first.back();
  61.         }
  62.         choice -= ending->second;
  63.     }
  64.     const bool wrongRandomNumber = true;
  65.     assert(!wrongRandomNumber);
  66.     return 0;
  67. }
  68.  
  69. std::string PickBegining(const TDistribution &distribution) {
  70.     size_t sum = 0;
  71.     for (const auto &item : distribution) {
  72.         sum += item.second;
  73.     }
  74.     if (sum == 0) {
  75.         return 0;
  76.     }
  77.     size_t choice = Random(0, sum - 1);
  78.     for (const auto &item : distribution) {
  79.         if (choice < item.second) {
  80.             return item.first;
  81.         }
  82.         choice -= item.second;
  83.     }
  84.     const bool wrongRandomNumber = true;
  85.     assert(!wrongRandomNumber);
  86.     return "";
  87. }
  88.  
  89. std::string GenerateText(const TDistribution &distribution, size_t length) {
  90.     std::string text = PickBegining(distribution);
  91.     while (text.length() < length) {
  92.         char next = PickNext(distribution, text.substr(text.length() - LIMIT + 1));
  93.         if (next == 0) {
  94.             break;
  95.         }
  96.         text += next;
  97.     }
  98.     return text;
  99. }
  100.  
  101. int main() {
  102.     auto distribution = ReadModel();
  103.     PrintModel(distribution);
  104.  
  105.     auto text = GenerateText(distribution, LENGTH);
  106.     std::cout << text << std::endl;
  107.  
  108.     return 0;
  109. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement