Advertisement
deced

Untitled

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