Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include"codes.h"
- /**
- Function merge two arrays in one
- @param res A pointer to the resulting array
- @param mas1 A pointer to the first array
- @param mas2 A pointer to the second array
- @param size_mas1 The size of the first array
- @param size_mas2 The size of the second array
- **/
- void difference::copy(int * res,int * mas1, int *mas2, int size_mas1, int size_mas2)
- {
- int g = 0;
- for (int i = 0 ;i < size_mas1; i++)
- {
- res[i] = mas1[i];
- }
- for (int i = size_mas1; i < size_mas2 + size_mas1; i++, g++)
- {
- res[i] = mas2[g];
- }
- };
- /**
- Function generating code composition
- @param a A reference to the first difference codes preserving
- @param b A reference to the second difference codes preserving
- **/
- void difference::composition(difference& a, difference& b)
- {
- int count = 0;
- int j = 0;
- int g = 0;
- int step = 1;
- int cmp;
- while (1)
- {
- for (; g < b.n - 1; g++)
- {
- copy(mas[count], a.mas[j], b.mas[g], a.size, b.size);
- count++;
- if ((count >= n) || (g == b.n - 1 && j == a.n - 1))
- {
- return;
- }
- }
- if (step * t + step >= a.n)
- {
- cmp = n - 1;
- }
- else
- {
- cmp = step * t + step;
- }
- for (; j <= cmp - 1; j++)
- {
- if ((count >= n) || (g == b.n - 1 && j == a.n - 1))
- {
- n = count;
- return;
- }
- copy(mas[count], a.mas[j], b.mas[g], a.size, b.size);
- count++;
- }
- j = step * t + step;
- if (j >= a.n)
- {
- j = a.n - 1;
- }
- for (; g >= 0; g--)
- {
- copy(mas[count], a.mas[j], b.mas[g], a.size, b.size);
- count++;
- if ((count >= n) || (g == b.n - 1 && j == a.n - 1))
- {
- n = count;
- return;
- }
- }
- g++;
- step++;
- j++;
- if (step * t + step >= a.n)
- {
- cmp = a.n - 1;
- }
- else
- {
- cmp = step * t + step;
- }
- for (; j <= cmp; j++)
- {
- copy(mas[count], a.mas[j], b.mas[g], a.size, b.size);
- count++;
- if ((count >= n) || (g == b.n - 1 && j == a.n - 1))
- {
- n = count;
- return;
- }
- }
- j--;
- g++;
- }
- int v = count;
- while (count != n)
- {
- delete mas[count];
- count++;
- }
- n = v;
- };
- /**
- The function counts the number of units in the code
- @param A pointer to an array, where the code is stored
- @return One unit number
- **/
- int difference::one(int *k)
- {
- int c = 0;
- for (int i = 0; i < size; i++)
- {
- if (k[i] == 1)
- {
- c++;
- }
- }
- return c;
- };
- /**
- The algorithm builds short codes brute force.
- @param res A pointer to the resulting two-dimensional array
- @param tmp A pointer to a two-dimensional array for intermediate
- @param mas A pointer to a two-dimensional array containing all possible codes
- @param flag A pointer to an array of bool type elements
- @param si Item number for which you choose the code
- @param maxi Variable reference which kept the maximum number of codes Built
- **/
- void difference::build(int** res, int **tmp, int **mas, bool* flag , int si, int& maxi)
- {
- if (maxi == n)
- {
- return;
- }
- for (int i = 0; i != degree(size); i++)
- {
- if (flag[i] == true)
- {
- if (si == 0)
- {
- memcpy(tmp[si], mas[i], size * sizeof(int));
- flag[i] = false;
- build(res, tmp, mas, flag, si + 1, maxi);
- flag[i] = true;
- continue;
- }
- else
- {
- if (condition1(tmp[si - 1], mas[i], si, si - 1))
- {
- if (i < t - 1 )
- {
- memcpy(tmp[si], mas[i],size * sizeof(int));
- flag[i] = false;
- build(res, tmp, mas, flag, si + 1, maxi);
- flag[i] = true;
- continue;
- }
- else
- {
- if (condition2(tmp, mas[i], si, si - 1 - t))
- {
- memcpy(tmp[si], mas[i], size * sizeof(int));
- flag[i] = false;
- build(res, tmp, mas, flag, si + 1, maxi);
- flag[i] = true;
- continue;
- }
- }
- }
- }
- }
- }
- if ((maxi < si)||((si == n) && (maxi != n)))
- {
- maxi = si;
- for (int i = 0; i < si; i++)
- {
- for (int j = 0; j < size; j++)
- {
- res[i][j] = tmp[i][j];
- }
- }
- }
- };
- /**
- Look for the code number of different units of the original
- @param res A pointer to a two-dimensional array where our code is stored
- @param A pointer to a two-dimensional array containing all possible codes
- @param i The number of original code in the array "res"
- @param si The number in the array which "res" will be stored code found
- **/
- void difference::find(int** res, int **mas, int i, int si)
- {
- for (int g = 0; g <= si; g++)
- {
- if (condition1(res[i-1], mas[g], i, i-1))
- {
- if(i <= t )
- {
- if (one(res[i - 1]) + 1 == one(mas[g]))
- {
- memcpy(res[i],mas[g],size * sizeof(int));
- return;
- }
- }
- }
- }
- };
- /**
- Raises 2 to any degree
- @param deg degree
- @return 2 a given degree
- **/
- int difference::degree(int deg)
- {
- int f = 1;
- for (int i = 1; i <= deg; i++)
- {
- f *= 2;
- }
- return f;
- };
- /**
- Build all the possible combinations of zeros and ones of the given size
- @param size Combinations of size
- @return A pointer to a two-dimensional array, which contains all combinations
- **/
- int ** difference::combinat(int size)
- {
- int f = degree(size);
- int c = 0;
- int z = 0;
- int **mas = new int* [f + 1];
- for (int i = 0; i <= f; i++)
- {
- mas[i] = new int [size + 1];
- }
- for (int i = 0; i <= f; i++)
- {
- c = i;
- z = (i >> 1);
- c = c ^ z;
- binary(mas[i], c, size);
- }
- return mas;
- };
- /**
- Seeking a Hamming distance of two codes
- @param i A pointer to the first code
- @param j A pointer to the second code
- @return Hamming distance
- **/
- int difference::hamming(int *i, int *j)
- {
- int count = 0;
- for (int g = 0; g < size; g++)
- {
- if (i[g] != j[g])
- {
- count++;
- }
- }
- return count;
- };
- /**
- Checks codes on the first condition
- @param i A pointer to the first code
- @param j A pointer to the second code
- @param num Number of the first code
- @param num2 Number of the second code
- @return true if satisfy condition,else false
- **/
- bool difference::condition1(int *i, int *j, int num , int num2)
- {
- int res = num - num2;
- if (res < 0)
- {
- res = res * (-1);
- }
- if (res <= t)
- {
- if (hamming(i,j) == res)
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- else
- {
- return false;
- }
- };
- /**
- Checks codes on the second condition
- @param i A pointer to the first code
- @param j A pointer to the second code
- @param num Number of the first code
- @param num2 Number of the second code
- @return true if satisfy condition,else false
- **/
- bool difference::condition2(int **i, int *j, int num, int num2)
- {
- int count = 0;
- int res = num - num2;
- int u = 0;
- if (res < 0)
- {
- res = res * (-1);
- }
- u = num2;
- int y = 0;
- if (res > t)
- {
- while(num2 >= 0)
- {
- y = hamming(i[num2], j);
- if (hamming(i[num2], j) > t )
- {
- count ++;
- }
- num2 --;
- }
- if (count == (u + 1))
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- else
- {
- return false;
- }
- };
- /**
- It translates into a binary representation
- @param mas A pointer to the resulting array
- @param i The number that you want to translate
- @param size The size of the resulting array
- **/
- void difference::binary(int *mas, int i, int size)
- {
- int c = 0;
- for (int g = 0; g < size; g++)
- {
- mas[g] = 0;
- }
- while (i != 0)
- {
- c = i % 2;
- i = i / 2;
- size --;
- mas[size] = c;
- }
- };
- /**
- The class constructor
- @param par_n Parameter n
- @param par_size Parameter size
- @param par_t Parameter t
- **/
- difference::difference(int par_n, int par_size, int par_t)
- {
- n = par_n;
- size = par_size;
- t = par_t;
- if (size ==0)
- {
- return ;
- }
- int c = 0;
- int v = 0;
- if (n == 0)
- {
- n = degree(size);
- }
- mas = new int* [n];
- for (int i = 0; i < n; i++)
- {
- mas[i] = new int [size];
- }
- if ((size < 5) && (t >= size))
- {
- int ** tmp = combinat(size);
- int u = degree(size);
- memcpy(mas[0], tmp[0], size * sizeof (int));
- for (int i = 1; i < n; i++)
- {
- find(mas, tmp, i, u);
- if (one(mas[i]) == 0)
- {
- v = i;
- while (v != n)
- {
- delete mas[v];
- v++;
- }
- n = i;
- }
- }
- delete *tmp;
- return;
- }
- if (size < 6)
- {
- int ** tmp = combinat(size);
- int u = degree(size);
- int **result = new int* [n];
- bool *flag = new bool [u];
- for (int i = 0; i < n; i++)
- {
- result[i] = new int [size];
- }
- for (int i = 0; i < u; i++)
- {
- flag[i] = true;
- }
- int max = 0;
- build(mas, result, tmp, flag, 0, max);
- n = max;
- delete *result;
- delete flag;
- }
- else
- {
- if (0 == size % 2)
- {
- c = size / 2;
- difference ab(0, c, t);
- (*this).composition(ab, ab);
- }
- else
- {
- c = size / 2;
- v = c + 1;
- difference ab(0, c, t);
- difference bb(0, v, t);
- (*this).composition(ab, bb);
- }
- }
- };
- /**
- Retains constructed codes
- @param filename The file name to save
- **/
- void difference::save( char* filename)
- {
- ofstream file (filename);
- for (int i = 0; i < n; i++)
- {
- file<< i << " ";
- for (int z = 0; z < size; z++)
- {
- file << mas[i][z];
- }
- file << endl;
- }
- file.close();
- };
- /**
- The class Destructor
- **/
- difference::~difference()
- {
- delete [] mas;
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement