#pragma once #include #include #include #include #include // работа с файлами #include void permutation(int n, std::vector& arr_comb, std::vector < std::vector >& comb_s) { //Размещения с повторением 2^n if (n < 0) { std::cout << "нельзя отрицательные\n"; return; } if (n == 0) { for (int i = 0; i <= arr_comb.size() - 1; i++) std::cout << arr_comb[i] << " "; std::cout << "\n"; comb_s.push_back(arr_comb); return; } else { for (int i = 0;i <= 1;i++) { arr_comb[arr_comb.size() - n] = i + '0'; permutation(n - 1, arr_comb, comb_s); } } } class DP_CODE { private: unsigned int n = 0; unsigned int t = 0; unsigned int flag = 0; std::vector < std::vector > codes; unsigned int arr_rang[5][5] = { 2,2,2,2,2,3,3,3,3,3,5,4,4,4,4,8,6,5,5,5,14,8,7,6,6 }; unsigned int rank = 0; std::vector < std::vector > comb_s; //все комбинации 2^n std::vector bool_comb_s;// флажок, помогающий понять использован код или нет из 2 ^ n public: class DP_CODE(unsigned int n, unsigned int t) { this->n = n; this->t = t; this->rank = arr_rang[n - 1][t - 1]; std::cout << this->rank << " НАЧАЛО \n"; } unsigned int H_comparison(std::vector arr_comb1, std::vector arr_comb2) { //функция сравнивает коды по условию int t1 = 0; unsigned int count = 0; for (int i = 0;i < n;i++) { t1 = abs((arr_comb1[i] - '0') - (arr_comb2[i] - '0')); if (t1 > 0) { count++; } } return count; } void print2(std::vector arr_comb) { for (int j = 0; j < arr_comb.size(); j++) { std::cout << arr_comb[j]; } std::cout << "\n"; } void add_code(std::vector arr_code,int index) { codes[index] = arr_code; for (int i = 0; i < n; i++) { codes[index][i] = arr_code[i]; } } void fillingcodes(int size_codes) { std::cout << "rank=" << size_codes << "\n"; if (size_codes == rank) { for (int i = 0;i < codes.size();i++) { print2(codes[i]); } //добавить флаг,что надо прерывать цикл flag = 1; return; } else { for (int i = 0;i < comb_s.size();i++) { if (flag == 1) break; if (bool_comb_s[i] == 0) { if (size_codes == 0) { add_code(comb_s[i], size_codes);//добавить элемент bool_comb_s[i] = 1; fillingcodes(size_codes + 1); if (flag == 0) bool_comb_s[i] = 0; } else { int index = 0; int count = 0; for (int j = 0;j < size_codes; j++) { //сравниаем с теми ,которые уже есть в std::vector < std::vector > codes; if (H_comparison(comb_s[i], codes[j]) <= t) { count = count + 1; if (count == 1) { index = j; } } if (count==1) { //дать вомзожность может когда встречается больеш чем надо? if ((abs(size_codes - index) <= t) && ((size_codes - index) != 0)) { add_code(comb_s[i], size_codes); bool_comb_s[i] = 1; fillingcodes(size_codes + 1); if (flag == 0) bool_comb_s[i] = 0; } } if (flag == 1) break; } } } } } } void creating_codes() { if (n < 6 && t < 6) { int count_comb_s = pow(2, n); bool_comb_s.resize(count_comb_s); std::vector arr_comb(n); //вспомогательный массив ,нужен только в permutation permutation(n, arr_comb, comb_s); //перебор всех комбинаций codes.resize(rank); fillingcodes(0); } else { codes =composition(n, t); } } std::vector merge(std::vector code_1, std::vector code_2) { std::vector code_3; code_3.resize(code_1.size() + code_2.size());//возможно ошибка for (int i = 0; i < code_1.size(); i++) { code_3[i] = code_1[i]; } int j = 0; for (int i = code_1.size(); i < code_3.size(); i++) { code_3[i] = code_2[j]; j++; } return code_3; } void printf_file(std::string a) { std::string c = a + ".txt"; std::ofstream fout(c, std::ofstream::app); if (!fout.is_open()) { std::cout << "Error"; return; } else { std::cout << "All okey\n"; for (int i = 0; i < codes.size(); i++) { for (int j = 0; j < n; j++) { std::cout<< codes[i][j]<<" "; fout << codes[i][j]; } fout << "\n"; std::cout << "\n"; } } fout.close(); // закрываем файл } void read_file(std::string a, std::vector < std::vector > & codes_1) { char ch; int i = 0; int j = 0; std::cout << codes_1.size() <<" "; std::string c = a + ".txt"; std::ifstream fin(c);//чтение данных if (!fin.is_open()) { std::cout << "Error"; } else { std::cout << "All okey\n"; while (fin.get(ch)) { if (ch == '0'|| ch == '1') { codes_1[i][j] = ch; j++; if (j == codes_1[0].size()) { j = 0; i++; } } } } fin.close(); } std::vector < std::vector >add_limit(std::vector < std::vector > codes_1, std::vector < std::vector > codes_2, unsigned int t_1, unsigned int u_2, unsigned int rank_1) { std::vector < std::vector > codes_3; codes_3.resize(rank_1); unsigned int rank_t=1; unsigned int i = 1; unsigned int g = 0; unsigned int j = 0; while (rank_t<=rank_1) //пока не набрали нужное количество по рангу { while (g < i * t_1) { //от 0 до i*t_1-1,по идее верно if (rank_t == rank_1) { break; } codes_3[rank_t-1]=merge(codes_1[g], codes_2[j]); g++; rank_t++; } g++; while (j < i * u_2) { if (rank_t == rank_1) { break; } codes_3[rank_t - 1]=merge(codes_1[g], codes_2[j]); j++; rank_t++; } j++; i++; if (rank_t == rank_1) { break; } } return codes_3; } std::vector < std::vector > increase_rank(std::vector < std::vector > codes_1, std::vector < std::vector > codes_2, unsigned int t_1, unsigned int u_2, unsigned int rank_1) { std::vector < std::vector > codes_3; //нужно учесть длину одного вектора codes_3.resize(rank_1); unsigned int rank_t = 1; unsigned int i = 1; unsigned int g = 0; int j = 0; unsigned int M = codes_2.size(); //всего M элелементов while (rank_t <= rank_1) //пока не набрали нужное количество по рангу { std::cout << rank_t<<"\n"; while (j =0) { //ошибка if (rank_t == rank_1) { break; } codes_3[rank_t - 1] = merge(codes_1[g], codes_2[j]); j--; rank_t++; } j = 0; //чтобы убрать -1 g++; i++; //4) while (g < i * t_1 + i) { if (rank_t == rank_1) { break; } codes_3[rank_t - 1] = merge(codes_1[g], codes_2[j]); g++; rank_t++; } g++; i++; if (rank_t == rank_1) { break; } } return codes_3; } std::vector < std::vector > composition(unsigned int n_1, unsigned int t_1) { unsigned int n_2 = 0, t_2 = 0, m = 0, u = 0; int mode=0; std::vector < std::vector > codes_1; std::vector < std::vector > codes_2; unsigned int rank_1=0; if (n_1 == 1 && t_1 > 6) { // обращаемся к файлу нужному codes_1.resize(2); for (int i = 0; i < 2; i++) { codes_1[i].resize(1); } read_file("11", codes_1); return codes_1; } if (n_1 < 6 && t_1 < 6) { //добавить условие для 1 и любыъ t // обращаемся к файлу нужному codes_1.resize(arr_rang[n_1 - 1][t_1 - 1]); for (int i = 0; i < arr_rang[n_1 - 1][t_1 - 1]; i++) { codes_1[i].resize(n_1); } std::string a = std::to_string(n_1); std::string b = std::to_string(t_1); read_file(a+b, codes_1); return codes_1; } mode = 0; n_2 = n_1 / 2; t_2 = t_1 / 2; m = n_1 / 2 + n_1 % 2; u = t_1 / 2 + t_1 % 2; if (t_1 > 5) { //возможно надо доработать условие mode = 0; n_2 = n_1 / 2; t_2 = t_1 / 2; m = n_1 / 2 + n_1 % 2; u = t_1 / 2 + t_1 % 2; } else { if (n_1 > 5) { mode = 1; n_2 = n_1 / 2; t_2 = t_1; m = n_1 / 2 + n_1 % 2; u = t_1; } } codes_1=composition(n_2,t_2); //левая часть codes_2=composition(m,u); //правая часть unsigned int N = codes_1.size(); //количество кодов unsigned int M = codes_2.size(); //количество кодов if (mode == 0) { if (((M - 1) / u) >= ((N - 1) / t_2)) rank_1 = N + ((N - 1) / t_2) * u; else rank_1 = M+t_2+ ((M - 1) / u)*t_2; return add_limit(codes_1, codes_2, t_2, u, rank_1); } else { rank_1 = M * (N / (t_2 + 1)) + t_2 * (N / (t_2 + 1)); return increase_rank(codes_1, codes_2, t_2, u, rank_1); } } };