Advertisement
Guest User

Untitled

a guest
Dec 15th, 2018
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.02 KB | None | 0 0
  1. #include"codes.h"
  2. /**
  3.  Function merge two arrays in one
  4.  @param res A pointer to the resulting array
  5.  @param mas1 A pointer to the first array
  6.  @param mas2 A pointer to the second array
  7.  @param size_mas1 The size of the first array
  8.  @param size_mas2 The size of the second array
  9.  **/
  10.  
  11. void difference::copy(int * res,int * mas1, int *mas2, int size_mas1, int size_mas2)
  12. {
  13.     int g = 0;
  14.     for (int i = 0 ;i < size_mas1; i++)
  15.     {
  16.         res[i] = mas1[i];
  17.     }
  18.     for (int i = size_mas1; i < size_mas2 + size_mas1; i++, g++)
  19.     {
  20.         res[i] = mas2[g];
  21.     }
  22. };
  23. /**
  24.  Function generating code composition
  25.  @param a A reference to the first difference codes preserving
  26.  @param b A  reference to the second difference codes preserving
  27.  **/
  28. void difference::composition(difference& a, difference& b)
  29. {
  30.     int count = 0;
  31.     int j = 0;
  32.     int g = 0;
  33.     int step = 1;
  34.     int cmp;
  35.     while (1)
  36.     {
  37.         for (; g < b.n  - 1; g++)
  38.         {
  39.             copy(mas[count], a.mas[j], b.mas[g], a.size, b.size);
  40.             count++;
  41.             if ((count  >= n) || (g == b.n  - 1 && j == a.n  - 1))
  42.             {
  43.                 return;
  44.             }
  45.  
  46.         }
  47.         if (step * t + step >= a.n)
  48.         {
  49.             cmp = n - 1;
  50.         }
  51.         else
  52.         {
  53.             cmp = step * t + step;
  54.         }
  55.         for (; j <= cmp - 1; j++)
  56.         {
  57.             if ((count  >= n) || (g == b.n  - 1 && j == a.n  - 1))
  58.             {
  59.                 n = count;
  60.                 return;
  61.             }
  62.             copy(mas[count], a.mas[j], b.mas[g], a.size, b.size);
  63.             count++;
  64.         }
  65.         j = step * t + step;
  66.         if (j >= a.n)
  67.         {
  68.             j = a.n - 1;
  69.         }
  70.         for (; g >= 0; g--)
  71.         {
  72.  
  73.             copy(mas[count], a.mas[j], b.mas[g], a.size, b.size);
  74.             count++;
  75.             if ((count  >= n) || (g == b.n  - 1 && j == a.n  - 1))
  76.             {
  77.                 n = count;
  78.                 return;
  79.             }  
  80.         }
  81.         g++;
  82.         step++;
  83.         j++;
  84.         if (step * t + step >= a.n)
  85.         {
  86.             cmp = a.n - 1;
  87.         }
  88.         else
  89.         {
  90.             cmp = step * t + step;
  91.         }
  92.         for (; j <= cmp; j++)
  93.         {
  94.             copy(mas[count], a.mas[j], b.mas[g], a.size, b.size);
  95.             count++;
  96.             if ((count  >= n) || (g == b.n  - 1 && j == a.n  - 1))
  97.             {
  98.                 n = count;
  99.                 return;
  100.             }
  101.  
  102.         }
  103.         j--;
  104.         g++;
  105.     }
  106.     int v = count;
  107.     while (count != n)
  108.     {
  109.         delete mas[count];
  110.         count++;
  111.     }
  112.     n = v;
  113. };
  114. /**
  115. The function counts the number of units in the code
  116. @param A pointer to an array, where the code is stored
  117. @return  One unit number
  118. **/
  119. int difference::one(int *k)
  120. {
  121.     int c = 0;
  122.     for (int i = 0; i < size; i++)
  123.     {
  124.         if (k[i] == 1)
  125.         {
  126.             c++;
  127.         }
  128.     }
  129.     return c;
  130. };
  131. /**
  132. The algorithm builds short codes brute force.
  133. @param res A pointer to the resulting two-dimensional array
  134. @param tmp A pointer to a two-dimensional array for intermediate
  135. @param mas A pointer to a two-dimensional array containing all possible codes
  136. @param flag A pointer to an array of bool type elements
  137. @param si Item number for which you choose the code
  138. @param maxi Variable reference which kept the maximum number of codes Built
  139. **/
  140. void difference::build(int** res, int **tmp, int **mas, bool* flag , int si, int& maxi)
  141. {
  142.  
  143.     if (maxi == n)
  144.     {
  145.         return;
  146.     }
  147.     for (int i = 0; i != degree(size); i++)
  148.     {
  149.         if (flag[i] == true)
  150.         {
  151.             if (si == 0)
  152.             {
  153.                 memcpy(tmp[si], mas[i], size * sizeof(int));
  154.                 flag[i] = false;
  155.                 build(res, tmp, mas, flag, si + 1, maxi);
  156.                 flag[i] = true;
  157.                 continue;          
  158.             }
  159.             else
  160.             {
  161.                 if (condition1(tmp[si - 1], mas[i], si, si - 1))
  162.                 {
  163.                     if (i < t - 1 )
  164.                     {
  165.                         memcpy(tmp[si], mas[i],size * sizeof(int));
  166.                         flag[i] = false;
  167.                         build(res, tmp, mas, flag, si + 1, maxi);
  168.                         flag[i] = true;
  169.                         continue;
  170.  
  171.                     }
  172.                     else
  173.                     {
  174.                         if (condition2(tmp, mas[i], si, si - 1 - t))
  175.                         {
  176.                             memcpy(tmp[si], mas[i], size * sizeof(int));
  177.                             flag[i] = false;
  178.                             build(res, tmp, mas, flag, si + 1, maxi);
  179.                             flag[i] = true;
  180.                             continue;
  181.                         }
  182.                     }
  183.                 }
  184.             }
  185.         }
  186.     }
  187.     if ((maxi < si)||((si == n) && (maxi != n)))
  188.     {
  189.         maxi = si;
  190.         for (int i = 0; i < si; i++)
  191.         {
  192.             for (int j = 0; j < size; j++)
  193.             {
  194.                 res[i][j] = tmp[i][j];
  195.             }
  196.         }
  197.     }
  198. };
  199. /**
  200. Look for the code number of different units of the original
  201. @param res A pointer to a two-dimensional array where our code is stored
  202. @param A pointer to a two-dimensional array containing all possible codes
  203. @param i The number of original code in the array "res"
  204. @param si The number in the array which "res" will be stored code found
  205. **/
  206. void difference::find(int** res, int **mas, int i, int si)
  207. {
  208.     for (int g = 0; g <= si; g++)
  209.     {
  210.        
  211.             if (condition1(res[i-1], mas[g], i, i-1))
  212.             {
  213.                 if(i <= t )
  214.                 {
  215.                     if (one(res[i - 1]) + 1 == one(mas[g]))
  216.                     {
  217.                         memcpy(res[i],mas[g],size * sizeof(int));
  218.                         return;
  219.                     }
  220.             }
  221.         }
  222.     }
  223. };
  224. /**
  225. Raises 2 to any degree
  226. @param deg degree
  227. @return 2 a given degree
  228. **/
  229.     int difference::degree(int deg)
  230. {
  231.     int f = 1;
  232.     for (int i = 1; i <= deg; i++)
  233.     {
  234.         f *= 2;
  235.     }
  236.     return f;
  237. };
  238.     /**
  239.     Build all the possible combinations of zeros and ones of the given size
  240.     @param size Combinations of size
  241.     @return A pointer to a two-dimensional array, which contains all combinations
  242.     **/
  243. int ** difference::combinat(int size)
  244. {
  245.     int f = degree(size);
  246.     int c = 0;
  247.     int z = 0;
  248.     int **mas = new int* [f + 1];
  249.     for (int i = 0; i <= f; i++)
  250.     {
  251.         mas[i] = new int [size + 1];
  252.     }
  253.     for (int i = 0; i <= f; i++)
  254.     {
  255.         c = i;
  256.         z = (i >> 1);
  257.         c = c ^ z;
  258.         binary(mas[i], c, size);
  259.     }
  260.     return mas;
  261. };
  262. /**
  263. Seeking a Hamming distance of two codes
  264. @param i A pointer to the first code
  265. @param j A pointer to the second code
  266. @return Hamming distance
  267. **/
  268. int  difference::hamming(int *i, int *j)
  269. {
  270.     int count = 0;
  271.     for (int g = 0; g < size; g++)
  272.     {
  273.         if (i[g] != j[g])
  274.         {
  275.             count++;
  276.         }
  277.     }
  278.     return count;
  279. };
  280. /**
  281. Checks codes on the first condition
  282. @param i A pointer to the first code
  283. @param j A pointer to the second code
  284. @param num Number of the first code
  285. @param num2 Number of the second code
  286. @return true if satisfy condition,else false
  287.  
  288. **/
  289. bool difference::condition1(int *i, int *j, int num , int num2)
  290. {
  291.     int res = num - num2;
  292.     if (res < 0)
  293.     {
  294.         res = res * (-1);
  295.     }
  296.     if (res <= t)
  297.     {
  298.         if (hamming(i,j) == res)
  299.         {
  300.             return true;
  301.         }
  302.         else
  303.         {
  304.             return false;
  305.         }
  306.  
  307.     }
  308.     else
  309.     {
  310.         return false;
  311.     }
  312. };
  313. /**
  314. Checks codes on the second condition
  315. @param i A pointer to the first code
  316. @param j A pointer to the second code
  317. @param num Number of the first code
  318. @param num2 Number of the second code
  319. @return true if satisfy condition,else false
  320. **/
  321. bool difference::condition2(int **i, int *j, int num, int num2)
  322. {
  323.     int count = 0;
  324.     int res = num - num2;
  325.     int u = 0;
  326.     if (res < 0)
  327.     {
  328.         res = res * (-1);
  329.     }
  330.     u = num2;
  331.     int y = 0;
  332.     if (res > t)
  333.     {
  334.         while(num2 >= 0)
  335.         {
  336.             y = hamming(i[num2], j);
  337.             if (hamming(i[num2], j) > t )
  338.             {
  339.                 count ++;
  340.             }
  341.             num2 --;
  342.         }
  343.         if (count == (u + 1))
  344.         {
  345.             return true;
  346.         }
  347.         else
  348.         {
  349.             return false;
  350.         }
  351.     }
  352.     else
  353.     {
  354.         return false;
  355.     }
  356. };
  357. /**
  358. It translates into a binary representation
  359. @param mas A pointer to the resulting array
  360. @param i The number that you want to translate
  361. @param size The size of the resulting array
  362. **/
  363. void difference::binary(int *mas, int i, int size)
  364. {
  365.     int c = 0;
  366.     for (int g = 0; g < size;  g++)
  367.     {
  368.         mas[g] = 0;
  369.     }
  370.     while (i != 0)
  371.     {
  372.         c = i % 2;
  373.         i = i / 2;
  374.         size --;
  375.         mas[size] = c;
  376.  
  377.     }
  378. };
  379. /**
  380. The class constructor
  381. @param par_n Parameter n
  382. @param par_size Parameter size
  383. @param par_t Parameter t
  384. **/
  385. difference::difference(int par_n, int par_size, int par_t)
  386. {
  387.     n = par_n;
  388.     size = par_size;
  389.     t = par_t;
  390.     if (size ==0)
  391.     {
  392.         return ;
  393.     }
  394.     int c = 0;
  395.     int v = 0;
  396.     if (n == 0)
  397.     {
  398.         n = degree(size);
  399.     }
  400.     mas = new int* [n];
  401.     for (int i = 0; i < n; i++)
  402.     {
  403.         mas[i] = new int [size];
  404.  
  405.     }
  406.     if ((size < 5) && (t >= size))
  407.     {
  408.         int ** tmp = combinat(size);
  409.         int u = degree(size);
  410.         memcpy(mas[0], tmp[0],  size * sizeof (int));
  411.         for (int i = 1; i < n; i++)
  412.         {
  413.             find(mas, tmp, i, u);
  414.             if (one(mas[i]) == 0)
  415.             {
  416.                 v = i;
  417.                 while (v != n)
  418.                 {
  419.                     delete mas[v];
  420.                     v++;
  421.                 }
  422.                 n = i;
  423.  
  424.             }
  425.         }
  426.         delete *tmp;
  427.         return;
  428.     }
  429.     if (size < 6)
  430.     {
  431.         int ** tmp = combinat(size);
  432.         int u = degree(size);
  433.         int **result = new int* [n];
  434.         bool *flag = new bool [u];
  435.         for (int i = 0; i < n; i++)
  436.         {
  437.             result[i] = new int [size];  
  438.         }
  439.         for (int i = 0; i < u; i++)
  440.         {
  441.             flag[i] = true;
  442.         }
  443.         int max = 0;
  444.         build(mas, result, tmp, flag, 0, max);
  445.         n = max;
  446.         delete *result;
  447.         delete flag;
  448.     }
  449.     else
  450.     {
  451.         if (0 == size % 2)
  452.         {
  453.             c = size / 2;
  454.             difference ab(0, c, t);
  455.             (*this).composition(ab, ab);
  456.         }
  457.         else
  458.         {
  459.             c = size / 2;
  460.             v = c + 1;
  461.             difference ab(0, c, t);
  462.             difference bb(0, v, t);
  463.             (*this).composition(ab, bb);
  464.         }
  465.     }
  466. };
  467. /**
  468. Retains constructed codes
  469. @param filename The file name to save
  470. **/
  471. void difference::save( char* filename)
  472. {
  473.     ofstream file (filename);
  474.     for (int i = 0; i < n; i++)
  475.     {
  476.         file<< i << "  ";
  477.         for (int z = 0; z < size; z++)
  478.         {
  479.             file << mas[i][z];
  480.         }
  481.         file << endl;
  482.     }
  483.     file.close();
  484. };
  485. /**
  486. The class Destructor
  487. **/
  488. difference::~difference()
  489. {
  490.     delete [] mas;
  491. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement