Advertisement
AmidamaruZXC

Untitled

Apr 4th, 2020
165
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.26 KB | None | 0 0
  1.  
  2. #include <iostream>
  3. #include <fstream>
  4. #include <stdlib.h>
  5. #include <vector>
  6. using namespace std;
  7.  
  8. class ShannonFano {
  9.     struct Symbol {
  10.         friend ShannonFano;
  11.  
  12.         Symbol(int frequency)
  13.         {
  14.             this->frequency = frequency;
  15.         }
  16.  
  17.         int frequency;
  18.         string code;
  19.     };
  20.  
  21. public:
  22.  
  23.     void build()
  24.     {
  25.         fano(0, _symbols.size() - 1);
  26.     }
  27.  
  28.     void addChance(int chance)
  29.     {
  30.         _symbols.emplace_back(Symbol(chance));
  31.     }
  32.  
  33.     string get(int i)
  34.     {
  35.         return _symbols[i].code;
  36.     }
  37.  
  38. private:
  39.     // recursively picks up codes for symbols from _symbols in the range [begin;end]
  40.     // begin - index of the first symbol
  41.     // end - index of the last symbol
  42.     void fano(int begin, int end)
  43.     {
  44.         if (begin >= end)//may be equal?
  45.             return;
  46.  
  47.         int medIndex = getMedianIndex(begin, end);
  48.         for (int i = begin; i <= end; ++i)
  49.             _symbols[i].code += (i > medIndex) ? "1" : "0";
  50.  
  51.         fano(begin, medIndex);
  52.         fano(medIndex + 1, end);
  53.     }
  54.  
  55.     // finds index med (begin <= med < end) and sum of frequences
  56.     // _symbols[beign..med] is closest to sum of frequences of
  57.     // _symbols[med+1..end]
  58.     int getMedianIndex(int begin, int end)
  59.     {
  60.         int leftSum = 0;
  61.         for (int i = begin; i < end; ++i)
  62.             leftSum += _symbols[i].frequency;
  63.         int rightSum = _symbols[end].frequency;
  64.  
  65.         int med = end;
  66.         int delta;
  67.         do
  68.         {
  69.             delta = leftSum - rightSum;
  70.             --med;
  71.             leftSum -= _symbols[med].frequency;
  72.             rightSum += _symbols[med].frequency;
  73.         } while (abs(leftSum - rightSum) <= delta);
  74.  
  75.         return med;
  76.     }
  77.  
  78.  
  79. private:
  80.  
  81.     vector<Symbol> _symbols;
  82. };
  83.  
  84.  
  85.  
  86. int main() {
  87.  
  88.     int n;
  89.     ShannonFano* shf = new ShannonFano();
  90.  
  91.     fstream fin;
  92.     fin.open("input.txt", ios::in);
  93.     if (fin.is_open()) {
  94.         fin >> n;
  95.         for (int i = 0; i < n; i++) {
  96.             int x;
  97.             fin >> x;
  98.             shf->addChance(x);
  99.         }
  100.  
  101.         fin.close();
  102.  
  103.         shf->build();
  104.         fstream fout;
  105.         fout.open("output.txt", ios::out);
  106.         for (int i = 0; i < n; i++) {
  107.             fout << shf->get(i) << (i == n - 1 ? "" : " ");
  108.         }
  109.         fout.close();
  110.         delete shf;
  111.  
  112.     }
  113.     return 0;
  114. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement