SHARE
TWEET

tapemap

Lazerate Feb 27th, 2020 (edited) 226 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <iostream>
  2. #include <fstream>
  3. #include <string>
  4. #include <sstream>
  5. #include <thread>
  6. #include <map>
  7. #include <algorithm>
  8. #include <vector>
  9. #include <mutex>
  10. #include <functional>
  11.  
  12. class tapemx {
  13.  
  14.     size_t px, py;
  15.     std::map<std::pair<size_t, size_t>, int> mx;
  16.     std::mutex m;
  17.  
  18. public:
  19.  
  20.     tapemx readmx(std::string fn);
  21.     tapemx(const tapemx& copy) : m{}, px(copy.px), py(copy.py), mx(copy.mx) {};
  22.     tapemx() : m{} {};
  23.     friend bool mulmx(tapemx&& tmx1, tapemx&& tmx2, std::ofstream& out);
  24.     friend bool addmx(tapemx&& tmx1, tapemx&& tmx2, std::ofstream& out);
  25.  
  26. };
  27.  
  28.  
  29. /*Чтение из файла и запись в матрицу
  30. Читаем линию, а затем в потоке парсим её на составляющие
  31. и записываем строчку матрицы в класс*/
  32. tapemx tapemx::readmx(std::string fn) {
  33.  
  34.     std::ifstream in;
  35.     in.open(fn);
  36.  
  37.     std::string line;
  38.  
  39.     if (in.is_open()) {
  40.  
  41.         std::vector<std::thread> thr;
  42.  
  43.         short cnt(0); //счетчик строк
  44.  
  45.         while (std::getline(in, line)) {
  46.             thr.emplace_back([cnt, line, this]() {
  47.                 short tmp_cnt(0); //счетчик столбцов
  48.  
  49.                 std::stringstream ss(line);
  50.                 std::string ts;
  51.  
  52.                 while (std::getline(ss, ts, ' ')) {
  53.                     int tx = std::stoi(ts);
  54.                     if (tx) {
  55.                         std::lock_guard<std::mutex> guard(m);
  56.                         ((*this).mx)[{cnt, tmp_cnt}] = tx;
  57.                     }
  58.                     ++tmp_cnt;
  59.                 }
  60.  
  61.                 if (!cnt) (*this).px = tmp_cnt;
  62.                 });
  63.             ++cnt;
  64.         }
  65.  
  66.         for_each(thr.begin(), thr.end(), std::mem_fn(&std::thread::join));
  67.  
  68.         (*this).py = cnt;
  69.     }
  70.     in.close();
  71.     return *this; // не возвращается
  72. }
  73.  
  74. /*Умножение матриц
  75. Получаем матрицы, над которыми производятся операции
  76. во второй меняем представление с
  77. {строки, столбцы} на {столбцы строки}
  78. Пишем умножение в файл*/
  79. bool mulmx(tapemx&& tmx1, tapemx&& tmx, std::ofstream& out) {
  80.  
  81.     if (!(tmx1.px == tmx.py)) {
  82.         out.close();
  83.         return false;
  84.     }
  85.  
  86.     std::map<std::pair<size_t, size_t>, int> tmx2;
  87.  
  88.     for (auto i = tmx.mx.begin(); i != tmx.mx.end(); i++) {
  89.         tmx2[{std::move(i->first.second), std::move(i->first.first)}] = std::move(i->second);
  90.     }
  91.  
  92.     std::map<std::pair<int, int>, std::pair<size_t, int>> tmp;
  93.  
  94.     auto ii = tmx1.mx.begin();
  95.     std::vector<std::thread> thr;
  96.  
  97.     for (auto i = ii; i != tmx1.mx.end(); i++) {
  98.  
  99.         int zh(0);//счетчик количества нулевых строчек
  100.  
  101.         auto& key = i->first;
  102.         auto& bound = ii->first;
  103.         key.first != bound.first ? zh = key.first - bound.first - 1 : zh = bound.first;
  104.  
  105.         if (zh) {
  106.             while (zh--) {
  107.                 tmp[{key.first - zh, 0}] = { tmx.px, 0 };
  108.             }
  109.         }
  110.  
  111.         auto jj = tmx2.begin();
  112.         i = (i != ii ? ++ii : ii); //меняем ii на текущую строку для дальнейшего
  113.                                    //пропуска всех значений текущей
  114.         for (auto j = jj; j != tmx2.end();) {
  115.  
  116.             thr.emplace_back([j, jj, i, ii, &tmx1, &tmx2, &tmp]() {
  117.                 int zrh(0); //счетчик нулей между ячейками
  118.  
  119.                 j != jj ? zrh = j->first.first - jj->first.first - 1 : zrh = jj->first.first - 0;
  120.                 int x(0);
  121.  
  122.                 for (auto k = i; k != tmx1.mx.end(); k++) {
  123.                     if (k->first.first != ii->first.first) break; //проходим только по текущей строке
  124.                     try {
  125.                         int tr = tmx2.at({ j->first.first, k->first.second }); //есть на что умножать — делаем
  126.                         x += k->second * tr;
  127.                     }
  128.                     catch (std::out_of_range) {
  129.                         continue;
  130.                     }
  131.                 }
  132.  
  133.                 if (zrh) {
  134.                     tmp[{i->first.first, j->first.first - zrh}] = { zrh, 0 };
  135.                 }
  136.                 tmp[{i->first.first, j->first.first}] = { 1, x };
  137.  
  138.                 });
  139.  
  140.             jj = (j != jj ? ++jj : jj); //меняем jj на текущий столбец для
  141.                                         //пропуска всех значений текущего
  142.             while ((j != tmx2.end()) && (j->first.first == jj->first.first)) {
  143.                 jj = j++;
  144.             }
  145.  
  146.         }
  147.  
  148.         size_t bias = tmx.px - (jj->first.first + 1);
  149.  
  150.         if (bias) {
  151.             thr.emplace_back([i, bias, &tmx, &tmp]() {
  152.                 tmp[{i->first.first, tmx.px - 1}] = { bias, 0 };
  153.                 });
  154.         }
  155.  
  156.         while ((i != tmx1.mx.end()) && (i->first.first == ii->first.first)) {
  157.             ii == i++; // пропуск значений текущей строки
  158.         }
  159.  
  160.         i = ii;
  161.     }
  162.  
  163.     for_each(thr.begin(), thr.end(), std::mem_fn(&std::thread::join));
  164.  
  165.     auto bi = tmp.begin();
  166.  
  167.     for (auto i = bi; i != tmp.end();) {
  168.         if (bi->first.first != i->first.first) out << "\n";
  169.  
  170.         while ((i->second.first)--) {
  171.             out << i->second.second << " ";
  172.         }
  173.  
  174.         bi = i++;
  175.     }
  176.  
  177.     out.close();
  178.     return true;
  179. }
  180.  
  181. /*Сложение(оно работает, и работает хорошо)
  182. Получаем матрицы, сразу слагаем их
  183. и выводим в файл*/
  184. bool addmx(tapemx&& tmx1, tapemx&& tmx2, std::ofstream& out) {
  185.  
  186.     if (!((tmx1.px == tmx2.px) && (tmx1.py == tmx2.py))) {
  187.         out.close();
  188.         return false;
  189.     }
  190.  
  191.     for (auto i = tmx2.mx.begin(); i != tmx2.mx.end(); i++) { //идем по матрице, которую прибавляем
  192.         auto& key = i->first;
  193.         try {
  194.             tmx1.mx.at({ key.first, key.second }) += std::move(*i).second; //если есть значение по
  195.                                                                            //этим координатам — прибавляем
  196.         }
  197.         catch (std::out_of_range) {
  198.             tmx1.mx[{ key.first, key.second}] = std::move(*i).second; //просто заносим в первую матрицу
  199.         }
  200.     }
  201.  
  202.     auto ii = tmx1.mx.begin(); //граничное значение для проверки
  203.  
  204.     for (auto i = ii; i != tmx1.mx.end(); i++) {
  205.  
  206.         int zh(0); //количество нулевых строк
  207.  
  208.         auto& key = i->first;
  209.         auto& bound = ii->first;
  210.         i != ii ? zh = key.first - bound.first - 1 : zh = bound.first;
  211.  
  212.         if (zh) {
  213.             while (zh--) {
  214.                 for (size_t i = 0; i < tmx1.px; i++) {
  215.                     out << "0 "; //вывод нулевых строк
  216.                 }
  217.             }
  218.             out << "\n";
  219.         }
  220.  
  221.         auto prev = (i != ii ? ++ii : ii); //отслеживание текущей строки
  222.         while ((i != tmx1.mx.end()) && i->first.first == prev->first.first) {
  223.             int zrh(0); //количество нулей между ячейками
  224.             i != ii ? zrh = i->first.second - prev->first.second - 1 : zrh = ii->first.second;
  225.  
  226.             if (zrh) {
  227.                 while (zrh--) {
  228.                     out << "0 "; //вывод нулей
  229.                 }
  230.             }
  231.  
  232.             out << i->second << " "; //вывод значения
  233.  
  234.             prev = i++; //в итоге в prev окажется
  235.                         //последний элемент строки
  236.         }
  237.         for (size_t j = prev->first.second + 1; j < tmx1.px; j++) {
  238.             out << "0 "; //оставшиеся до конца строки нули
  239.         }
  240.         out << "\n";
  241.  
  242.         ii = i = prev;
  243.     }
  244.  
  245.     out.close();
  246.     return true;
  247. }
  248.  
  249. int main(int argc, char* argv[]) {
  250.  
  251.     tapemx tpm1, tpm2;
  252.  
  253.    /* std::ofstream out1;
  254.     out1.open("tapeadd.txt", std::ios::app);
  255.  
  256.     if (out1.is_open()) {
  257.         if (!addmx(tpm1.readmx("tape1.txt"), tpm2.readmx("tape2.txt"), out1)) {
  258.             std::cout << "Wrong matrix sizes" << std::endl;
  259.             system("pause");
  260.         }
  261.     }*/
  262.     std::ofstream out2;
  263.     out2.open("tapemul.txt", std::ios::app);
  264.  
  265.     if (out2.is_open()) {
  266.         if (!mulmx(tpm1.readmx("tape1.txt"), tpm2.readmx("tape3.txt"), out2)) {
  267.             std::cout << "Wrong matrix sizes" << std::endl;
  268.             system("pause");
  269.         }
  270.     }
  271.  
  272.     system("pause");
  273.  
  274.     return 0;
  275. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top