Advertisement
deced

Untitled

Nov 9th, 2020
162
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 7.97 KB | None | 0 0
  1. program Lab3_3;
  2.  
  3. uses System.Sysutils, System.StrUtils, System.Generics.Collections, IOUtils;
  4.  
  5. type
  6.     InputType = (FromConsole, FromFile);
  7.     IntArray = array of Integer;
  8.     TListOfTList = TList<TList<Integer>>;
  9.  
  10. const
  11.     MaxArraySize = 100000000;
  12.     outputDirectory = 'output.txt';
  13.     MsgEnterInputType = 'Выберите способ ввода файл/консоль (ф/к)';
  14.     MsgEnterFilePath = 'Введите путь к файлу';
  15.     MsgNoSuchFile = 'Файл не найден. Попробуйте ещё раз';
  16.     MsgEnterArray = 'Введите элементы массива, разделённые запятыми';
  17.     MsgEnterArraySize = 'Введите размер массива';
  18.     MsgArraySizeFormatError =
  19.       'Размер массива должен быть числом от 1 до 100000000';
  20.     MsgGetOutputDirectory =
  21.       'Введите директорию в которую хотите сохранить вывод';
  22.     MsgArrayFormatError =
  23.       'Входная строка должна содеражать только числа разделённые запятыми';
  24.     MsgNoSuchDirectory = 'Указанная директория не найдена, попробуйте ещё раз';
  25.     MsgSortedArray = 'Сортировка массива по этапам:';
  26.  
  27. function GetInputType(): InputType;
  28. var
  29.     Answer: InputType;
  30.     Input: String;
  31.     IsCorrect: Boolean;
  32. begin
  33.     IsCorrect := False;
  34.     repeat
  35.         Writeln(MsgEnterInputType);
  36.         Readln(Input);
  37.         Input := AnsiLowerCase(Input);
  38.         if Input.Equals('ф') or Input.Equals('файл') then
  39.         begin
  40.             Answer := InputType.FromFile;
  41.             IsCorrect := True;
  42.         end
  43.         else if Input.Equals('к') or Input.Equals('консоль') then
  44.         begin
  45.             Answer := InputType.FromConsole;
  46.             IsCorrect := True;
  47.         end;
  48.     until IsCorrect;
  49.     GetInputType := Answer;
  50. end;
  51.  
  52. function GetInputFilePath(): AnsiString;
  53. var
  54.     Path: AnsiString;
  55.     IsCorrect: Boolean;
  56. begin
  57.     IsCorrect := False;
  58.     repeat
  59.         Writeln(MsgEnterFilePath);
  60.         Readln(Path);
  61.         if FileExists(Path) then
  62.             IsCorrect := True
  63.         else
  64.             Writeln(MsgNoSuchFile);
  65.  
  66.     until IsCorrect;
  67.     GetInputFilePath := Path;
  68. end;
  69.  
  70. function GetArraySize(): Integer;
  71. var
  72.     IsCorrect: Boolean;
  73.     Size: Integer;
  74. begin
  75.     repeat
  76.         IsCorrect := True;
  77.         Writeln(MsgEnterArraySize);
  78.         try
  79.             Readln(Size);
  80.         except
  81.             Writeln(MsgArraySizeFormatError);
  82.             IsCorrect := False;
  83.         end;
  84.  
  85.         if ((Size < 1) or (Size > MaxArraySize)) and IsCorrect then
  86.         begin
  87.             Writeln(MsgArraySizeFormatError);
  88.             IsCorrect := False;
  89.         end;
  90.     until IsCorrect;
  91.     GetArraySize := Size;
  92. end;
  93.  
  94. function GetArrayFromConsole(Size: Integer): IntArray;
  95. var
  96.     InputArray: IntArray;
  97.     IsCorrect: Boolean;
  98.     InputLine: String;
  99.     SplittedString: TArray<String>;
  100.     I: Integer;
  101. begin
  102.     SetLength(InputArray, Size);
  103.     dec(Size);
  104.     repeat
  105.         IsCorrect := True;
  106.         Writeln(MsgEnterArray);
  107.         IsCorrect := True;
  108.         Readln(InputLine);
  109.         SplittedString := SplitString(InputLine, ',');
  110.         try
  111.             for I := 0 to Size do
  112.                 InputArray[I] := StrToInt(SplittedString[I]);
  113.         except
  114.             Writeln(MsgArrayFormatError);
  115.             IsCorrect := False;
  116.         end;
  117.     until IsCorrect;
  118.     GetArrayFromConsole := InputArray;
  119. end;
  120.  
  121. function GetArrayFromFile(Size: Integer): IntArray;
  122. var
  123.     InputArray: IntArray;
  124.     IsCorrect: Boolean;
  125.     FilePath, InputLine: String;
  126.     InputFile: TextFile;
  127.     SplittedString: TArray<String>;
  128.     I: Integer;
  129. begin
  130.     SetLength(InputArray, Size);
  131.     dec(Size);
  132.     repeat
  133.         IsCorrect := True;
  134.         FilePath := GetInputFilePath();
  135.         AssignFile(InputFile, FilePath);
  136.         Reset(InputFile);
  137.         Readln(InputFile, InputLine);
  138.         SplittedString := SplitString(InputLine, ',');
  139.         try
  140.             for I := 0 to Size do
  141.                 InputArray[I] := StrToInt(SplittedString[I]);
  142.         except
  143.             Writeln(MsgArrayFormatError);
  144.             IsCorrect := False;
  145.         end;
  146.     until IsCorrect;
  147.     GetArrayFromFile := InputArray;
  148. end;
  149.  
  150. function GetArray(): IntArray;
  151. var
  152.     InputArray: IntArray;
  153.     SelectedInputType: InputType;
  154.     Size: Integer;
  155. begin
  156.     SelectedInputType := GetInputType();
  157.     Size := GetArraySize();
  158.     if SelectedInputType = InputType.FromConsole then
  159.         InputArray := GetArrayFromConsole(Size)
  160.     else if SelectedInputType = InputType.FromFile then
  161.         InputArray := GetArrayFromFile(Size);
  162.     GetArray := InputArray;
  163. end;
  164.  
  165. procedure InitFileAndConsole();
  166. var
  167.     OutputFile: TextFile;
  168. begin
  169.     AssignFile(OutputFile, outputDirectory);
  170.     Rewrite(OutputFile);
  171.     Writeln(OutputFile, MsgSortedArray);
  172.     Writeln(MsgSortedArray);
  173.     CloseFile(OutputFile);
  174. end;
  175.  
  176. procedure PrintToFile(ToPrint: String);
  177. begin
  178.     TFile.AppendAllText(outputDirectory, #13#10 + ToPrint);
  179. end;
  180.  
  181. procedure PrintToConsole(ToPrint: String);
  182. begin
  183.     Writeln(ToPrint);
  184. end;
  185.  
  186. function PrintPreSorted(ToPrint: TListOfTList): String;
  187. var
  188.     StringToPrint: String;
  189.     I, J: Integer;
  190. begin
  191.     StringToPrint := '';
  192.     for I := 0 to ToPrint.Count - 1 do
  193.     begin
  194.         StringToPrint := StringToPrint + '[';
  195.         for J := 0 to ToPrint[I].Count - 1 do
  196.         begin
  197.             StringToPrint := StringToPrint + IntToStr(ToPrint[I][J]);
  198.             if J + 1 < ToPrint[I].Count then
  199.                 StringToPrint := StringToPrint + ', ';
  200.         end;
  201.         StringToPrint := StringToPrint + ']';
  202.     end;
  203.     PrintToConsole(StringToPrint);
  204.     PrintToFile(StringToPrint);
  205. end;
  206.  
  207. procedure PrintEndInfo();
  208. begin
  209.     Writeln(Format('Вывод сохранён по пути %s\%s', [GetCurrentDir(),
  210.       outputDirectory]));
  211. end;
  212.  
  213. function SplitArray(ToSplit: IntArray): TListOfTList;
  214. var
  215.     ListOfParts: TListOfTList;
  216.     Part: TList<Integer>;
  217.     I: Integer;
  218. begin
  219.     ListOfParts := TList < TList < Integer >>.Create();
  220.     Part := TList<Integer>.Create();
  221.     for I := 0 to High(ToSplit) do
  222.         if (Part.Count = 0) or (Part[Part.Count - 1] < ToSplit[I]) then
  223.             Part.Add(ToSplit[I])
  224.         else
  225.         begin
  226.             ListOfParts.Add(Part);
  227.             Part := TList<Integer>.Create();
  228.             Part.Add(ToSplit[I]);
  229.         end;
  230.     ListOfParts.Add(Part);
  231.     SplitArray := ListOfParts;
  232. end;
  233.  
  234. function MergeSort(ToSort: IntArray): IntArray;
  235. var
  236.     ListOfParts: TListOfTList;
  237.     NewPart: TList<Integer>;
  238.     NewPartLength, I: Integer;
  239.     SortedArray: IntArray;
  240.  
  241. begin
  242.     ListOfParts := SplitArray(ToSort);
  243.     while (ListOfParts.Count > 1) do
  244.     begin
  245.         PrintPreSorted(ListOfParts);
  246.         NewPart := TList<Integer>.Create();
  247.         NewPartLength := ListOfParts[0].Count + ListOfParts[1].Count;
  248.         for I := 0 to NewPartLength - 1 do
  249.             if (ListOfParts[1].Count = 0) or
  250.               ((ListOfParts[0].Count > 0) and
  251.               (ListOfParts[0][0] < ListOfParts[1][0])) then
  252.             begin
  253.  
  254.                 NewPart.Add(ListOfParts[0][0]);
  255.                 ListOfParts[0].Delete(0);
  256.             end
  257.             else
  258.             begin
  259.                 NewPart.Add(ListOfParts[1][0]);
  260.                 ListOfParts[1].Delete(0);
  261.             end;
  262.         ListOfParts.Delete(0);
  263.         ListOfParts[0] := NewPart;
  264.     end;
  265.     PrintPreSorted(ListOfParts);
  266.     SetLength(SortedArray, ListOfParts[0].Count - 1);
  267.     for I := 0 to ListOfParts[0].Count - 1 do
  268.         SortedArray[I] := ListOfParts[0][I];
  269.     MergeSort := SortedArray;
  270. end;
  271.  
  272. var
  273.     UnSortedArray: IntArray;
  274.  
  275. begin
  276.     UnSortedArray := GetArray();
  277.     InitFileAndConsole();
  278.     MergeSort(UnSortedArray);
  279.     PrintEndInfo();
  280.     Readln;
  281.  
  282. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement