Advertisement
believe_me

Untitled

Nov 29th, 2021
238
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 15.98 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <iomanip>
  4. #include <cstdlib>
  5. #include <fstream>
  6.  
  7.  
  8. bool checkPermissionForWriting(const std::string& PathToFile) {
  9.     bool Flag;
  10.     std::ofstream FileOut(PathToFile);
  11.     if (FileOut.is_open()) {
  12.         FileOut.close();
  13.         Flag = true;
  14.     }
  15.     else {
  16.         std::cout << "File isn't available for writing.\n";
  17.         Flag = false;
  18.     }
  19.     return Flag;
  20. }
  21.  
  22. bool checkPermissionForReading(const std::string& PathToFile) {
  23.     bool Flag;
  24.     std::ifstream FileIn(PathToFile);
  25.     if (FileIn.is_open()) {
  26.         FileIn.close();
  27.         Flag = true;
  28.     }
  29.     else {
  30.         std::cout << "File isn't available for reading.\n";
  31.         Flag = false;
  32.     }
  33.     return Flag;
  34. }
  35.  
  36. bool checkExtension(const std::string& PathToFile) {
  37.     const std::string extension = "txt";
  38.     bool Flag;
  39.     if (PathToFile.length() > 4 && PathToFile.substr(PathToFile.length() - 3) == extension) {
  40.         Flag = true;
  41.     }
  42.     else {
  43.         std::cout << "Wrong extension.\n";
  44.         Flag = false;
  45.     }
  46.     return Flag;
  47. }
  48.  
  49. void printSourceArrayInConsole(int* SourceArray, int NumberOfElements) {
  50.     std::cout << "Source array:\n";
  51.     for (int i = 0; i < NumberOfElements; i++) {
  52.         std::cout << std::setw(6) << SourceArray[i];
  53.     }
  54.     std::cout << "\n";
  55. }
  56.  
  57. int inputIntegerNumber(const int MIN_NUMBER, const int MAX_NUMBER) {
  58.     bool is_incorrect;
  59.     int number;
  60.     std::string input = "";
  61.     do {
  62.         getline(std::cin, input);
  63.         is_incorrect = false;
  64.         try {
  65.             number = std::stoi(input);
  66.         }
  67.         catch (std::invalid_argument ex) {
  68.             std::cout << "Enter a number:\n";
  69.             is_incorrect = true;
  70.         }
  71.         catch (std::out_of_range ex) {
  72.             std::cout << "Number mustn't be less than " << MIN_NUMBER << " and more than "
  73.                 << MAX_NUMBER << "\n";
  74.             is_incorrect = true;
  75.         }
  76.         if (!is_incorrect && (number <  MIN_NUMBER || number > MAX_NUMBER)) {
  77.             std::cout << "Number mustn't be less than " << MIN_NUMBER << " and more than "
  78.                 << MAX_NUMBER << "\n";
  79.             is_incorrect = true;
  80.         }
  81.     } while (is_incorrect);
  82.     return number;
  83. }
  84.  
  85. int chooseWayOfInput() {
  86.     const int CONSOLE_INPUT = 1;
  87.     const int FILE_INPUT = 2;
  88.     const int RANDOM_GENERATION_INPUT = 3;
  89.     int UserWay;
  90.     do {
  91.         UserWay = inputIntegerNumber(1, 3);
  92.     } while (UserWay != CONSOLE_INPUT && UserWay != FILE_INPUT && UserWay != RANDOM_GENERATION_INPUT);
  93.     return UserWay;
  94. }
  95.  
  96. int chooseWayOfOutput() {
  97.     const int CONSOLE_OUTPUT = 1;
  98.     const int FILE_OUTPUT = 2;
  99.     int UserWay;
  100.     do {
  101.         UserWay = inputIntegerNumber(1, 2);
  102.     } while (UserWay != CONSOLE_OUTPUT && UserWay != FILE_OUTPUT);
  103.     return UserWay;
  104. }
  105.  
  106. int inputNumberOfElements() {
  107.     std::cout << "Input number of elements:\n";
  108.     return inputIntegerNumber(2, 200);
  109. }
  110.  
  111. int inputElement() {
  112.     std::cout << "Input element: ";
  113.     return inputIntegerNumber(-100, 100);
  114. }
  115.  
  116. bool checkFile(const std::string PathToFile) {
  117.     bool Flag = true;
  118.     int IsNumber;
  119.     std::string Text;
  120.     std::ifstream InputFile(PathToFile);
  121.     getline(InputFile, Text);
  122.     int SizeOfText = Text.length();
  123.     for (int i = 0; (i < SizeOfText && Flag); i++) {
  124.         if (Text[i] != ' ' && Text[i] != '-') {
  125.             try {
  126.                 IsNumber = std::stoi(Text.substr(i, 1));
  127.             }
  128.             catch (std::invalid_argument ex) {
  129.                 std::cout << "Received data includes non-integer chars.\n";
  130.                 Flag = false;
  131.             }
  132.         }
  133.     }
  134.     InputFile.close();
  135.     if (Text[0] == NULL) {
  136.         Flag = 0;
  137.         std::cout << "File is empty\n";
  138.     }
  139.     return Flag;
  140. }
  141.  
  142. int receiveNumberOfElementsFromFile(const std::string PathToFile) {
  143.     int NumberOfElements = 0;
  144.     int Element;
  145.     std::ifstream InputFile(PathToFile);
  146.     while (!InputFile.eof()) {
  147.         InputFile >> Element;
  148.         NumberOfElements++;
  149.     }
  150.     InputFile.close();
  151.     return NumberOfElements;
  152. }
  153.  
  154. const std::string inputPathToFileForReading() {
  155.     std::string PathToFile;
  156.     do {
  157.         std::cout << "Input path to file for reading:\n";
  158.         getline(std::cin, PathToFile);
  159.     } while (!checkExtension(PathToFile) || !checkPermissionForReading(PathToFile));
  160.     return PathToFile;
  161. }
  162.  
  163. void receiveSourceArrayFromFile(const std::string PathToFile, int* SourceArray) {
  164.     int i = 0;
  165.     std::string Text;
  166.     std::ifstream InputFile(PathToFile);
  167.     while (!InputFile.eof()) {
  168.         InputFile >> SourceArray[i++];
  169.     }
  170.     InputFile.close();
  171. }
  172.  
  173. int receiveNumberOfElements(int* UserWay, std::string& PathToFile) {
  174.     std::cout << "Choose way of input: \nType '1' if you want to receive sequence from console;\nType '2' if you want to receieve sequence from file;\nType '3' if you want to fill sequence with random numbers:\n";
  175.     int NumberOfElements;
  176.     *UserWay = chooseWayOfInput();
  177.     switch (*UserWay) {
  178.     case 1:
  179.     {
  180.         NumberOfElements = inputNumberOfElements();
  181.         break;
  182.     }
  183.     case 2:
  184.     {
  185.         do {
  186.             PathToFile = inputPathToFileForReading();
  187.         } while (!(checkPermissionForReading(PathToFile) && checkFile(PathToFile)));
  188.         NumberOfElements = receiveNumberOfElementsFromFile(PathToFile);
  189.         break;
  190.     }
  191.     case 3:
  192.     {
  193.         NumberOfElements = inputNumberOfElements();
  194.         break;
  195.     }
  196.     }
  197.     return NumberOfElements;
  198. }
  199.  
  200. void fillingSourceArrayFromConsole(int* SourceArray, int NumberOfElements) {
  201.     for (int i = 0; i < NumberOfElements; i++) {
  202.         std::cout << "Input element: ";
  203.         SourceArray[i] = inputIntegerNumber(-50, 50);
  204.     }
  205. }
  206.  
  207. int* fillingSourceArrayWithRandomNumbers(int* SourceArray, int NumberOfElements)
  208. {
  209.     srand(time(NULL));
  210.     for (int i = 0; i < NumberOfElements; i++)
  211.     {
  212.         SourceArray[i] = rand() % 101 - 50;
  213.     }
  214.     return SourceArray;
  215. }
  216.  
  217. void receiveSourceArray(int NumberOfElements, int* SourceArray, int* UserWay, const std::string& PathToFile) {
  218.     switch (*UserWay) {
  219.     case 1:
  220.     {
  221.         fillingSourceArrayFromConsole(SourceArray, NumberOfElements);
  222.         break;
  223.     }
  224.     case 2:
  225.     {
  226.         receiveSourceArrayFromFile(PathToFile, SourceArray);
  227.         break;
  228.     }
  229.     case 3:
  230.     {
  231.         fillingSourceArrayWithRandomNumbers(SourceArray, NumberOfElements);
  232.         break;
  233.     }
  234.     }
  235.     printSourceArrayInConsole(SourceArray, NumberOfElements);
  236. }
  237.  
  238. void fillingArrayWithZeros(int* SizesOfIntermediateArray, int NumberOfElements) {
  239.     int Counter = NumberOfElements / 2 + 1;
  240.     for (int i = 0; i < Counter; i++) {
  241.         SizesOfIntermediateArray[i] = 0;
  242.     }
  243. }
  244.  
  245. int findPositionToWriteSizesOfFirstSortingArray(int* SizesOfFirstSortingArray, int NumberOfElements) {
  246.     for (int i = 0; i < NumberOfElements; i++) {
  247.         if (SizesOfFirstSortingArray[i] == 0) {
  248.             return i;
  249.         }
  250.     }
  251. }
  252.  
  253. int findPositionToWriteSizesOfSecondSortingArray(int* SizesOfFSecondSortingArray, int NumberOfElements) {
  254.     for (int i = 0; i < NumberOfElements; i++) {
  255.         if (SizesOfFSecondSortingArray[i] == 0) {
  256.             return i;
  257.         }
  258.     }
  259. }
  260.  
  261. bool findConditionOfSorted(int* IntermediateArray, int NumberOfElements) {
  262.     int Counter = 0;
  263.     for (int i = 1; i < NumberOfElements; i++) {
  264.         if (IntermediateArray[i - 1] <= IntermediateArray[i]) {
  265.             Counter++;
  266.         }
  267.     }
  268.     return (Counter + 1 == NumberOfElements);
  269. }
  270.  
  271. void creatingFirstF(int* IntermediateArray, int* SourceArray, int NumberOfElements) {
  272.     for (int i = 0; i < NumberOfElements; i++) {
  273.         IntermediateArray[i] = SourceArray[i];
  274.     }
  275. }
  276.  
  277. void creatingSortedArray(int* SortedArray, int* IntermediateArray, int NumberOfElements) {
  278.     for (int i = 0; i < NumberOfElements; i++) {
  279.         SortedArray[i] = IntermediateArray[i];
  280.     }
  281. }
  282.  
  283. int findNumberOfPairs(int* SizesOfFirstSortingArray, int NumberOfElements) {
  284.     int Counter = NumberOfElements / 2 + 1;
  285.     int NullPosition = Counter;
  286.     for (int i = 0; i < Counter; i++) {
  287.         if (SizesOfFirstSortingArray[i] == 0) {
  288.             NullPosition = i;
  289.             i = Counter;
  290.         }
  291.     }
  292.     return NullPosition;
  293. }
  294.  
  295. void findSortedPart(int* IntermediateArray, int* sort, int NumberOfElements, int* Index, int* Length) {
  296.     int k = 0;
  297.     for (int i = *Index; i < NumberOfElements; i++) {
  298.         if (i + 1 < NumberOfElements) {
  299.             if (IntermediateArray[i] <= IntermediateArray[i + 1]) {
  300.                 k++;
  301.             }
  302.             else {
  303.                 i = NumberOfElements;
  304.             }
  305.         }
  306.     }
  307.     if (k > 0) {
  308.         int j = 0;
  309.         for (int i = *Index; i < *Index + k + 1; i++) {
  310.             sort[j] = IntermediateArray[i];
  311.             j++;
  312.         }
  313.     }
  314.     else {
  315.         sort[0] = IntermediateArray[*Index];
  316.     }
  317.     *Length = k + 1;
  318.     *Index += *Length;
  319. }
  320.  
  321. void fillFirstSortingArray(int* FirstSortingArray, int* sort, int* SizesOfFirstSortingArray, int NumberOfElements, int Length, int* IndexOfIntermediateArray) {
  322.     for (int i = *IndexOfIntermediateArray; i < *IndexOfIntermediateArray + Length; i++)
  323.     {
  324.         FirstSortingArray[i] = sort[i - *IndexOfIntermediateArray];
  325.     }
  326.     int NumberOfPosition = findPositionToWriteSizesOfFirstSortingArray(SizesOfFirstSortingArray, NumberOfElements);
  327.     SizesOfFirstSortingArray[NumberOfPosition] = Length;
  328.     *IndexOfIntermediateArray += Length;
  329. }
  330.  
  331. void fillingSecondSortingArray(int* SecondSortingArray, int* sort, int* SizesOfFSecondSortingArray, int NumberOfElements, int Length, int* IndexOfIntermediateArray) {
  332.     for (int i = *IndexOfIntermediateArray; i < *IndexOfIntermediateArray + Length; i++) {
  333.         SecondSortingArray[i] = sort[i - *IndexOfIntermediateArray];
  334.     }
  335.     int NumberOfPosition = findPositionToWriteSizesOfSecondSortingArray(SizesOfFSecondSortingArray, NumberOfElements);
  336.     SizesOfFSecondSortingArray[NumberOfPosition] = Length;
  337.     *IndexOfIntermediateArray += Length;
  338. }
  339.  
  340. void fillingSortingArrays(int* IntermediateArray, int* FirstSortingArray, int* SecondSortingArray, int* SizesOfFirstSortingArray, int* SizesOfFSecondSortingArray, int NumberOfElements) {
  341.     int Index = 0;
  342.     int IndexOfIntermediateArray = 0;
  343.     int Length = 0;
  344.     int condition = 0;
  345.     int* sort = new int[NumberOfElements];
  346.     fillingArrayWithZeros(SizesOfFirstSortingArray, NumberOfElements);
  347.     fillingArrayWithZeros(SizesOfFSecondSortingArray, NumberOfElements);
  348.     for (int i = 0; i < NumberOfElements; i += Length)
  349.     {
  350.         findSortedPart(IntermediateArray, sort, NumberOfElements, &Index, &Length);
  351.         if (condition % 2 == 0)
  352.         {
  353.             fillFirstSortingArray(FirstSortingArray, sort, SizesOfFirstSortingArray, NumberOfElements, Length, &IndexOfIntermediateArray);
  354.         }
  355.         else
  356.         {
  357.             fillingSecondSortingArray(SecondSortingArray, sort, SizesOfFSecondSortingArray, NumberOfElements, Length, &IndexOfIntermediateArray);
  358.         }
  359.         condition++;
  360.     }
  361.     delete[] sort;
  362. }
  363.  
  364. void printArray(int* SourceArray, int NumberOfElements, int* UserWay, std::string& PathToFile) {
  365.     switch (*UserWay) {
  366.     case 1:
  367.     {
  368.         for (int i = 0; i < NumberOfElements; i++) {
  369.             std::cout << std::setw(6) << SourceArray[i];
  370.         }
  371.         std::cout << '\n';
  372.         break;
  373.     }
  374.     case 2:
  375.     {
  376.         std::ofstream FileOut(PathToFile, std::ios_base::app);
  377.         for (int i = 0; i < NumberOfElements; i++) {
  378.             FileOut << std::setw(6) << SourceArray[i];
  379.         }
  380.         FileOut << '\n';
  381.         FileOut.close();
  382.         break;
  383.     }
  384.     }
  385. }
  386.  
  387. void receiveNewSourceArray(int* IntermediateArray, int* FirstSortingArray, int* SecondSortingArray, int* SizesOfFirstSortingArray,
  388.     int* SizesOfFSecondSortingArray, int NumberOfElements, int* UserWay, std::string& PathToFile) {
  389.     fillingSortingArrays(IntermediateArray, FirstSortingArray, SecondSortingArray, SizesOfFirstSortingArray, SizesOfFSecondSortingArray, NumberOfElements);
  390.     int Counter = findNumberOfPairs(SizesOfFirstSortingArray, NumberOfElements);
  391.     int Index = 0;
  392.     for (int i = 0; i < Counter; i++) {
  393.         int SizeOfFirstSortingArray = SizesOfFirstSortingArray[i];
  394.         int SizeOfSecondSortingArray = SizesOfFSecondSortingArray[i];
  395.         int j1 = Index;
  396.         int j2 = Index + SizeOfFirstSortingArray;
  397.         int z = Index;
  398.         while (z < Index + SizeOfFirstSortingArray + SizeOfSecondSortingArray) {
  399.             if ((j1 == Index + SizeOfFirstSortingArray) && (j2 != Index + SizeOfFirstSortingArray + SizeOfSecondSortingArray)) {
  400.                 for (j2; j2 < SizeOfFirstSortingArray + SizeOfSecondSortingArray + Index; j2++) {
  401.                     IntermediateArray[z++] = SecondSortingArray[j2];
  402.                 }
  403.             }
  404.             if ((j2 == Index + SizeOfFirstSortingArray + SizeOfSecondSortingArray) && (j1 != Index + SizeOfFirstSortingArray)) {
  405.                 for (j1; j1 < SizeOfFirstSortingArray + Index; j1++) {
  406.                     IntermediateArray[z++] = FirstSortingArray[j1];
  407.                 }
  408.             }
  409.             if ((FirstSortingArray[j1] < SecondSortingArray[j2]) && (j2 < NumberOfElements) && (j1 < NumberOfElements) && (z < Index + SizeOfFirstSortingArray + SizeOfSecondSortingArray)) {
  410.                 IntermediateArray[z++] = FirstSortingArray[j1++];
  411.             }
  412.             else {
  413.                 if ((SecondSortingArray[j2] < FirstSortingArray[j1]) && (j2 < NumberOfElements) && (j1 < NumberOfElements) && (z < Index + SizeOfFirstSortingArray + SizeOfSecondSortingArray)) {
  414.                     IntermediateArray[z++] = SecondSortingArray[j2++];
  415.                 }
  416.                 else {
  417.                     if ((SecondSortingArray[j2] == FirstSortingArray[j1]) && (j2 < NumberOfElements) && (j1 < NumberOfElements) && (z < Index + SizeOfFirstSortingArray + SizeOfSecondSortingArray)) {
  418.                         IntermediateArray[z++] = FirstSortingArray[j1++];
  419.                         IntermediateArray[z++] = SecondSortingArray[j2++];
  420.                     }
  421.                 }
  422.             }
  423.         }
  424.         Index += SizeOfFirstSortingArray + SizeOfSecondSortingArray;
  425.     }
  426.     printArray(IntermediateArray, NumberOfElements, UserWay, PathToFile);
  427. }
  428.  
  429. void sorting(int* SourceArray, int* SortedArray, int NumberOfElements, int* UserWay, std::string& PathToFile) {
  430.     int* IntermediateArray = new int[NumberOfElements];
  431.     int* FirstSortingArray = new int[NumberOfElements];
  432.     int* SecondSortingArray = new int[NumberOfElements];
  433.     int* SizesOfFirstSortingArray = new int[NumberOfElements / 2 + 1];
  434.     int* SizesOfFSecondSortingArray = new int[NumberOfElements / 2 + 1];
  435.     creatingFirstF(IntermediateArray, SourceArray, NumberOfElements);
  436.     while (!findConditionOfSorted(IntermediateArray, NumberOfElements)) {
  437.         receiveNewSourceArray(IntermediateArray, FirstSortingArray, SecondSortingArray, SizesOfFirstSortingArray,
  438.             SizesOfFSecondSortingArray, NumberOfElements, UserWay, PathToFile);
  439.     }
  440.     creatingSortedArray(SortedArray, IntermediateArray, NumberOfElements);
  441.     delete[] IntermediateArray;
  442.     delete[] FirstSortingArray;
  443.     delete[] SecondSortingArray;
  444.     delete[] SizesOfFirstSortingArray;
  445.     delete[] SizesOfFSecondSortingArray;
  446. }
  447.  
  448. void printSortedArrayInConsole(int* SortedArray, int NumberOfElements)
  449. {
  450.     std::cout << "Sorted array:\n";
  451.     for (int i = 0; i < NumberOfElements; i++)
  452.     {
  453.         std::cout << std::setw(6) << SortedArray[i];
  454.     }
  455.     std::cout << "\n";
  456. }
  457.  
  458. void printSortedArrayInFile(int* SortedArray, int NumberOfElements, const std::string PathToFile)
  459. {
  460.     std::ofstream FileOut(PathToFile, std::ios_base::app);
  461.     FileOut << "Sorted array:\n";
  462.     for (int i = 0; i < NumberOfElements; i++)
  463.     {
  464.         FileOut << std::setw(6) << SortedArray[i];
  465.     }
  466.     FileOut.close();
  467.     std::cout << "Result is written in file.\n";
  468. }
  469.  
  470. const std::string inputPathToFileForWriting() {
  471.     std::string PathToFile;
  472.     do {
  473.         std::cout << "Input path to file for writing:  \n";
  474.         getline(std::cin, PathToFile);
  475.     } while (!checkExtension(PathToFile) || !checkPermissionForWriting(PathToFile));
  476.     return PathToFile;
  477. }
  478.  
  479. void receiveWayOfOutput(int* UserWay, std::string& PathToFile) {
  480.     std::cout << "Choose way of output:\nType '1' if you want to print sorting and result in console.\nType '2' if you want to print sorting and result in file.\n";
  481.     *UserWay = chooseWayOfOutput();
  482.     switch (*UserWay) {
  483.     case 1:
  484.         std::cout << "Sorting:\n";
  485.         break;
  486.     case 2:
  487.     {
  488.         do {
  489.             PathToFile = inputPathToFileForWriting();
  490.         } while (!checkExtension(PathToFile) && !checkPermissionForWriting(PathToFile));
  491.         std::ofstream FileOut(PathToFile, std::ios::trunc);
  492.         FileOut << "Sorting:\n";
  493.         FileOut.close();
  494.         break;
  495.     }
  496.     }
  497. }
  498.  
  499. void printResult(int* SortedArray, int NumberOfElements, int* UserWay, std::string& PathToFile) {
  500.     switch (*UserWay) {
  501.     case 1:
  502.     {
  503.         printSortedArrayInConsole(SortedArray, NumberOfElements);
  504.         break;
  505.     }
  506.     case 2:
  507.     {
  508.         printSortedArrayInFile(SortedArray, NumberOfElements, PathToFile);
  509.         break;
  510.     }
  511.     }
  512.     std::cout << "Program is completed.";
  513. }
  514.  
  515. int main() {
  516.     std::string PathToFile = "";
  517.     int UserWay;
  518.     std::cout << "This program implements natural merge sorting.\n";
  519.     int NumberOfElements = receiveNumberOfElements(&UserWay, PathToFile);
  520.     int* SourceArray = new int[NumberOfElements];
  521.     receiveSourceArray(NumberOfElements, SourceArray, &UserWay, PathToFile);
  522.     int* SortedArray = new int[NumberOfElements];
  523.     receiveWayOfOutput(&UserWay, PathToFile);
  524.     sorting(SourceArray, SortedArray, NumberOfElements, &UserWay, PathToFile);
  525.     printResult(SortedArray, NumberOfElements, &UserWay, PathToFile);
  526.     delete[] SourceArray;
  527.     delete[] SortedArray;
  528. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement