Advertisement
believe_me

Untitled

May 27th, 2022
274
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.92 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <fstream>
  4. #include <string>
  5. #include <list>
  6. #include <iomanip>
  7.  
  8. using namespace std;
  9.  
  10.  
  11. int inputIntegerNumber(const int MIN_NUMBER, const int MAX_NUMBER) {
  12.     bool IsIncorrect;
  13.     int Number;
  14.     string Input = "";
  15.  
  16.     do {
  17.         getline(cin, Input);
  18.         IsIncorrect = false;
  19.         try {
  20.             Number = stoi(Input);
  21.         }
  22.         catch (invalid_argument ex) {
  23.             cout << "Введите число:\n";
  24.             IsIncorrect = true;
  25.         }
  26.         catch (out_of_range ex) {
  27.             cout << "Число не должно быть меньше " << MIN_NUMBER << " и больше, чем "
  28.                 << MAX_NUMBER << "\n";
  29.             IsIncorrect = true;
  30.         }
  31.         if (!IsIncorrect && (Number <  MIN_NUMBER || Number > MAX_NUMBER)) {
  32.             cout << "Число не должно быть меньше " << MIN_NUMBER << " и больше, чем "
  33.                 << MAX_NUMBER << "\n";
  34.             IsIncorrect = true;
  35.         }
  36.     } while (IsIncorrect);
  37.  
  38.     return Number;
  39. }
  40.  
  41. bool checkFile(const string PathToFile) {
  42.     bool Flag = true;
  43.     int CurrentNumber, NumberOfLines;
  44.     NumberOfLines = 0;
  45.     string Buffer;
  46.     ifstream InputFile(PathToFile);
  47.     while ((Flag) && (!InputFile.eof())) {
  48.         getline(InputFile, Buffer);
  49.         for (int i = 0; (i < Buffer.length()) && (Flag); i++)
  50.             if ((Buffer[i] != ' ') && (Buffer[i] != '(') && (Buffer[i] != ')') && (((int)Buffer[i] < (int)'0') || (int)Buffer[i] > (int)'9')) {
  51.                 Flag = false;
  52.                 cout << "Некорректные символы в файле.\n";
  53.             }
  54.         NumberOfLines++;
  55.     }
  56.     if (Flag) {
  57.         InputFile.seekg(0, ios_base::beg);
  58.         InputFile >> CurrentNumber;
  59.         if (CurrentNumber != (NumberOfLines - 1)) {
  60.             cout << "Неверное количество вершин.\n";
  61.             Flag = false;
  62.         }
  63.     }
  64.     InputFile.close();
  65.     return Flag;
  66. }
  67.  
  68. bool checkPermissionForWriting(const string& PathToFile) {
  69.     bool Flag;
  70.     ofstream FileOut(PathToFile);
  71.  
  72.     if (FileOut.is_open()) {
  73.         FileOut.close();
  74.         Flag = true;
  75.     }
  76.     else {
  77.         cout << "Файл не доступен для записи.\n";
  78.         Flag = false;
  79.     }
  80.  
  81.     return Flag;
  82. }
  83.  
  84.  
  85. bool checkExtension(const string& PathToFile) {
  86.     const string extension = "txt";
  87.     bool Flag;
  88.  
  89.     if (PathToFile.length() > 4 && PathToFile.substr(PathToFile.length() - 3) == extension) {
  90.         Flag = true;
  91.     }
  92.     else {
  93.         cout << "Неверное расширение.\n";
  94.         Flag = false;
  95.     }
  96.  
  97.     return Flag;
  98. }
  99.  
  100. bool checkPermissionForReading(const string& PathToFile) {
  101.     bool Flag;
  102.     ifstream FileIn(PathToFile);
  103.     if (FileIn.is_open()) {
  104.         FileIn.close();
  105.         Flag = true;
  106.     }
  107.     else {
  108.         cout << "Файл не доступен для чтения.\n";
  109.         Flag = false;
  110.     }
  111.     return Flag;
  112. }
  113.  
  114. const string inputPathToFileForReading() {
  115.     string PathToFile;
  116.     do {
  117.         cout << "Введите путь к файлу для чтения:\n";
  118.         getline(cin, PathToFile);
  119.     } while (!checkExtension(PathToFile) || !checkPermissionForReading(PathToFile) || !checkFile(PathToFile));
  120.     return PathToFile;
  121. }
  122.  
  123. const string inputPathToFileForWriting() {
  124.     string PathToFile;
  125.     do {
  126.         cout << "Введите путь к файлу для записи: \n";
  127.         getline(cin, PathToFile);
  128.     } while (!checkExtension(PathToFile) || !checkPermissionForWriting(PathToFile));
  129.     return PathToFile;
  130. }
  131.  
  132. struct TVertex {
  133.     int number;
  134.     int dist;
  135. };
  136.  
  137. typedef vector<list<TVertex>> TListArray;
  138. typedef vector<vector<int>> TMatrix;
  139.  
  140.  
  141. void printListArray(TListArray& ListArray) {
  142.     cout << "Списки инцидентности:\n";
  143.     for (int i = 0; i < ListArray.size(); i++) {
  144.         cout << i + 1 << ": ";
  145.         for (auto Iterator : ListArray[i])
  146.             cout << "->" << Iterator.number << '(' << Iterator.dist << ')';
  147.         cout << '\n';
  148.     }
  149. }
  150.  
  151. void printIncidentMatrix(TMatrix& IncidentMatrix) {
  152.     cout << "Матрица инциденций:\n" << "   ";
  153.     for (int i = 0; i < IncidentMatrix[0].size(); i++) {
  154.         cout << setw(2) << (char)(i + 97) << ' ';
  155.     }
  156.     cout << '\n';
  157.     for (int i = 0; i < IncidentMatrix.size(); i++) {
  158.         cout << i + 1 << ": ";
  159.         for (int j = 0; j < IncidentMatrix[i].size(); j++)
  160.             cout << setw(2) << IncidentMatrix[i][j] << " ";
  161.         cout << '\n';
  162.     }
  163.     cout << '\n';
  164. }
  165.  
  166. void addVertex(TListArray &ListArray, TVertex CurrentVertex, int Index) {
  167.     ListArray[Index].push_back(CurrentVertex);
  168. }
  169.  
  170. vector<TVertex> getVertices(string Buffer) {
  171.     vector<TVertex> Vertices;
  172.     TVertex CurrentVertex;
  173.     string Number, Dist;
  174.     int j;
  175.     for (int i = 1; i < Buffer.size(); i++) {
  176.         if (Buffer[i] != ' ') {
  177.             j = i;
  178.             while ((Buffer[j] != '(') && j < Buffer.size())
  179.                 Number += Buffer[j++];
  180.             j++;
  181.             while (Buffer[j] != ')' && j < Buffer.size())
  182.                 Dist += Buffer[j++];
  183.             if (Number != "") {
  184.                 CurrentVertex.number = stoi(Number);
  185.                 CurrentVertex.dist = stoi(Dist);
  186.                 Vertices.push_back(CurrentVertex);
  187.             }
  188.             i = j;
  189.             i++;
  190.             Number = "";
  191.             Dist = "";
  192.         }
  193.     }
  194.     return Vertices;
  195. }
  196.  
  197. void readFormFile(TListArray& ListArray, string PathToFile) {
  198.     int NumberOfVertices, VertexNumber, i;
  199.     string Buffer = "";
  200.     vector<TVertex> Vertices;
  201.     i = -1;
  202.     ifstream FileIn(PathToFile);
  203.     FileIn >> NumberOfVertices;
  204.     ListArray.resize(NumberOfVertices);
  205.     while (!FileIn.eof()) {
  206.         getline(FileIn, Buffer);
  207.         Vertices = getVertices(Buffer);
  208.         for (int j = 0; j < Vertices.size(); j++)
  209.             addVertex(ListArray, Vertices[j], i);
  210.         i++;
  211.     }
  212.     FileIn.close();
  213. }
  214.  
  215. TVertex inputVertex(int WrongNumber, int MaxIndexOfVertices) {
  216.     TVertex CurrentVertex;
  217.     bool IsIncorrect = true;
  218.     int VertexNumber, Dist;
  219.     do {
  220.         cout << "Введите номер следующей инцидентной вершины: ";
  221.         VertexNumber = inputIntegerNumber(1, MaxIndexOfVertices);
  222.         if (VertexNumber == WrongNumber) {
  223.             IsIncorrect = true;
  224.             cout << "Текущая вершина не может быть инцидентна данной.\n";
  225.         }
  226.         else{
  227.             IsIncorrect = false;
  228.             cout << "Введите расстояние до данной вершины: ";
  229.             Dist = inputIntegerNumber(-30, 30);
  230.             CurrentVertex.number = VertexNumber;
  231.             CurrentVertex.dist = Dist;
  232.         }
  233.         cout << '\n';
  234.     } while (IsIncorrect);
  235.     return CurrentVertex;
  236. }
  237.  
  238. void receiveListReprezentation(TListArray& ListArray) {
  239.     int NumberOfVertices, VertexNumber, CurrentNumberOfVertices;
  240.     TVertex Vertex;
  241.     cout << "Введите количество вершин:\n";
  242.     NumberOfVertices = inputIntegerNumber(1, 15);
  243.     ListArray.resize(NumberOfVertices);
  244.     for (int i = 0; i < NumberOfVertices; i++) {
  245.         cout << "Введите количество вершин, смежных с вершиной " << i + 1 << ":\n";
  246.         CurrentNumberOfVertices = inputIntegerNumber(0, NumberOfVertices - 1);
  247.         for (int j = 0; j < CurrentNumberOfVertices; j++) {
  248.             Vertex = inputVertex(i + 1, NumberOfVertices);
  249.             addVertex(ListArray, Vertex,  i);
  250.         }
  251.     }
  252. }
  253.  
  254. void receiveGraph(TListArray& ListArray) {
  255.     char Answer = 'q';
  256.     cout << "Введите '1', если хотите считать из файла. '2' - из консоли.\n";
  257.     do {
  258.         cin >> Answer;
  259.         cin.ignore(256, '\n');
  260.         if (Answer == '1') {
  261.             string PathToFile = inputPathToFileForReading();
  262.             readFormFile(ListArray, PathToFile);
  263.             cout << "Граф получен.\n";
  264.         }
  265.         else
  266.             if (Answer == '2') {
  267.                 receiveListReprezentation(ListArray);
  268.                 cout << "Граф получен.\n";
  269.             }
  270.             else
  271.                 cout << "Введите '1' или '2'.\n";
  272.     } while ((Answer != '1') && (Answer != '2'));
  273. }
  274.  
  275.  
  276. void receiveAdjacencyMatrix(TListArray& ListArray, TMatrix& AdjacencyMatrix){
  277.     for (int i = 0; i < ListArray.size(); i++) {
  278.         for (auto const& Iterator : ListArray[i]) {
  279.             AdjacencyMatrix[i][Iterator.number - 1] = Iterator.dist;
  280.         }
  281.     }
  282. }
  283.  
  284. void receiveResultMatrices(TMatrix& AdjacencyMatrix, TMatrix& DistMatrix, TMatrix& PrecMatrix) {
  285.     int NewDist;
  286.     for (int i = 0; i < AdjacencyMatrix.size();  i++) {
  287.         DistMatrix[i][i] = 0;
  288.         for (int j = 0; j < AdjacencyMatrix.size(); j++)
  289.             if (AdjacencyMatrix[i][j]) {
  290.                 DistMatrix[i][j] = AdjacencyMatrix[i][j];
  291.                 PrecMatrix[i][j] = i;
  292.             }
  293.     }
  294.     for (int t = 0; t < AdjacencyMatrix.size(); t++) {
  295.         for (int i = 0; i < AdjacencyMatrix.size(); i++) {
  296.             for (int j = 0; j < AdjacencyMatrix.size(); j++) {
  297.                 if (DistMatrix[i][t] < INT_MAX && DistMatrix[t][j] < INT_MAX) {
  298.                     NewDist = DistMatrix[i][t] + DistMatrix[t][j];
  299.                     if (NewDist < DistMatrix[i][j]) {
  300.                         DistMatrix[i][j] = NewDist;
  301.                         PrecMatrix[i][j] = PrecMatrix[t][j];
  302.                     }
  303.                 }
  304.             }
  305.         }
  306.     }
  307. }
  308.  
  309. void receiveGraphText(string& GraphText, TMatrix& AdjacencyMatrix, TMatrix& DistMatrix, TMatrix& PrecMatrix) {
  310.     cout << "Введите номер вершины, для которой нужно найти кратчайшие пути:\n";
  311.     int VertexNumber = inputIntegerNumber(0, (AdjacencyMatrix.size()) - 1);
  312.     VertexNumber--;
  313.     GraphText += "digraph G {";
  314.     GraphText += "  node [shape=circle]";
  315.     GraphText += "  {node [style=filled] ";
  316.     GraphText += to_string(VertexNumber + 1);
  317.     GraphText += "}";
  318.     for (int i = 0; i < AdjacencyMatrix.size(); i++)
  319.         for (int j = 0; j < AdjacencyMatrix.size(); j++)
  320.             if (AdjacencyMatrix[i][j]) {
  321.                 GraphText += "  ";
  322.                 GraphText += to_string(i + 1);
  323.                 GraphText += " -> ";
  324.                 GraphText += to_string(j + 1);
  325.                 GraphText += " [label=";
  326.                 GraphText += "\"";
  327.                 GraphText += to_string(AdjacencyMatrix[i][j]) + "\"";
  328.                 if (i == PrecMatrix[VertexNumber][j])
  329.                     GraphText += ",color=red";
  330.                 GraphText += "];";
  331.             }
  332.     GraphText += "}";
  333. }
  334.  
  335. void receiveGraphImage(string& GraphText) {
  336.     const char* COMAND_TEXT = " \"C:\\graphviz\\bin\\dot.exe\" - Tpng C:\\t\\k.gv - o C:\\Users\\user\\Desktop\\71с++\\Project1\\GraphsFiles\\picture.png";
  337.     ofstream fout("C:\\t\\k.gv");
  338.     fout << GraphText;
  339.     fout.close();
  340.     system(COMAND_TEXT);
  341.     cout << "Изображение графа получено. Программа завершена.";
  342. }
  343.  
  344. int main() {
  345.     system("chcp 1251");
  346.     TListArray ListArray;
  347.     receiveGraph(ListArray);
  348.     printListArray(ListArray);
  349.     TMatrix AdjacencyMatrix(ListArray.size(), vector<int>(ListArray.size(), 0));
  350.     receiveAdjacencyMatrix(ListArray, AdjacencyMatrix);
  351.     TMatrix DistMatrix(AdjacencyMatrix.size(), vector<int>(AdjacencyMatrix.size(), INT_MAX));
  352.     TMatrix PrecMatrix(AdjacencyMatrix.size(), vector<int>(AdjacencyMatrix.size(), INT_MAX));
  353.     receiveResultMatrices(AdjacencyMatrix, DistMatrix, PrecMatrix);
  354.     string GraphText;
  355.     receiveGraphText(GraphText, AdjacencyMatrix, DistMatrix, PrecMatrix);
  356.     receiveGraphImage(GraphText);
  357.     return 0;
  358. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement