Advertisement
believe_me

Untitled

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