Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- program Lab3_3;
- uses System.Sysutils, System.StrUtils, System.Generics.Collections, IOUtils;
- type
- InputType = (FromConsole, FromFile);
- IntArray = array of Integer;
- TListOfTList = TList<TList<Integer>>;
- const
- MaxArraySize = 100000000;
- outputDirectory = 'output.txt';
- MsgEnterInputType = 'Выберите способ ввода файл/консоль (ф/к)';
- MsgEnterFilePath = 'Введите путь к файлу';
- MsgNoSuchFile = 'Файл не найден. Попробуйте ещё раз';
- MsgEnterArray = 'Введите элементы массива, разделённые запятыми';
- MsgEnterArraySize = 'Введите размер массива';
- MsgArraySizeFormatError =
- 'Размер массива должен быть числом от 1 до 100000000';
- MsgGetOutputDirectory =
- 'Введите директорию в которую хотите сохранить вывод';
- MsgArrayFormatError =
- 'Входная строка должна содеражать только числа разделённые запятыми';
- MsgNoSuchDirectory = 'Указанная директория не найдена, попробуйте ещё раз';
- MsgSortedArray = 'Сортировка массива по этапам:';
- function GetInputType(): InputType;
- var
- Answer: InputType;
- Input: String;
- IsCorrect: Boolean;
- begin
- IsCorrect := False;
- repeat
- Writeln(MsgEnterInputType);
- Readln(Input);
- Input := AnsiLowerCase(Input);
- if Input.Equals('ф') or Input.Equals('файл') then
- begin
- Answer := InputType.FromFile;
- IsCorrect := True;
- end
- else if Input.Equals('к') or Input.Equals('консоль') then
- begin
- Answer := InputType.FromConsole;
- IsCorrect := True;
- end;
- until IsCorrect;
- GetInputType := Answer;
- end;
- function GetInputFilePath(): AnsiString;
- var
- Path: AnsiString;
- IsCorrect: Boolean;
- begin
- IsCorrect := False;
- repeat
- Writeln(MsgEnterFilePath);
- Readln(Path);
- if FileExists(Path) then
- IsCorrect := True
- else
- Writeln(MsgNoSuchFile);
- until IsCorrect;
- GetInputFilePath := Path;
- end;
- function GetArraySize(): Integer;
- var
- IsCorrect: Boolean;
- Size: Integer;
- begin
- repeat
- IsCorrect := True;
- Writeln(MsgEnterArraySize);
- try
- Readln(Size);
- except
- Writeln(MsgArraySizeFormatError);
- IsCorrect := False;
- end;
- if ((Size < 1) or (Size > MaxArraySize)) and IsCorrect then
- begin
- Writeln(MsgArraySizeFormatError);
- IsCorrect := False;
- end;
- until IsCorrect;
- GetArraySize := Size;
- end;
- function GetArrayFromConsole(Size: Integer): IntArray;
- var
- InputArray: IntArray;
- IsCorrect: Boolean;
- InputLine: String;
- SplittedString: TArray<String>;
- I: Integer;
- begin
- SetLength(InputArray, Size);
- dec(Size);
- repeat
- IsCorrect := True;
- Writeln(MsgEnterArray);
- IsCorrect := True;
- Readln(InputLine);
- SplittedString := SplitString(InputLine, ',');
- try
- for I := 0 to Size do
- InputArray[I] := StrToInt(SplittedString[I]);
- except
- Writeln(MsgArrayFormatError);
- IsCorrect := False;
- end;
- until IsCorrect;
- GetArrayFromConsole := InputArray;
- end;
- function GetArrayFromFile(Size: Integer): IntArray;
- var
- InputArray: IntArray;
- IsCorrect: Boolean;
- FilePath, InputLine: String;
- InputFile: TextFile;
- SplittedString: TArray<String>;
- I: Integer;
- begin
- SetLength(InputArray, Size);
- dec(Size);
- repeat
- IsCorrect := True;
- FilePath := GetInputFilePath();
- AssignFile(InputFile, FilePath);
- Reset(InputFile);
- Readln(InputFile, InputLine);
- SplittedString := SplitString(InputLine, ',');
- try
- for I := 0 to Size do
- InputArray[I] := StrToInt(SplittedString[I]);
- except
- Writeln(MsgArrayFormatError);
- IsCorrect := False;
- end;
- until IsCorrect;
- GetArrayFromFile := InputArray;
- end;
- function GetArray(): IntArray;
- var
- InputArray: IntArray;
- SelectedInputType: InputType;
- Size: Integer;
- begin
- SelectedInputType := GetInputType();
- Size := GetArraySize();
- if SelectedInputType = InputType.FromConsole then
- InputArray := GetArrayFromConsole(Size)
- else if SelectedInputType = InputType.FromFile then
- InputArray := GetArrayFromFile(Size);
- GetArray := InputArray;
- end;
- procedure InitFileAndConsole();
- var
- OutputFile: TextFile;
- begin
- AssignFile(OutputFile, outputDirectory);
- Rewrite(OutputFile);
- Writeln(OutputFile, MsgSortedArray);
- Writeln(MsgSortedArray);
- CloseFile(OutputFile);
- end;
- procedure PrintToFile(ToPrint: String);
- begin
- TFile.AppendAllText(outputDirectory, #13#10 + ToPrint);
- end;
- procedure PrintToConsole(ToPrint: String);
- begin
- Writeln(ToPrint);
- end;
- function PrintPreSorted(ToPrint: TListOfTList): String;
- var
- StringToPrint: String;
- I, J: Integer;
- begin
- StringToPrint := '';
- for I := 0 to ToPrint.Count - 1 do
- begin
- StringToPrint := StringToPrint + '[';
- for J := 0 to ToPrint[I].Count - 1 do
- begin
- StringToPrint := StringToPrint + IntToStr(ToPrint[I][J]);
- if J + 1 < ToPrint[I].Count then
- StringToPrint := StringToPrint + ', ';
- end;
- StringToPrint := StringToPrint + ']';
- end;
- PrintToConsole(StringToPrint);
- PrintToFile(StringToPrint);
- end;
- procedure PrintEndInfo();
- begin
- Writeln(Format('Вывод сохранён по пути %s\%s', [GetCurrentDir(),
- outputDirectory]));
- end;
- function SplitArray(ToSplit: IntArray): TListOfTList;
- var
- ListOfParts: TListOfTList;
- Part: TList<Integer>;
- I: Integer;
- begin
- ListOfParts := TList < TList < Integer >>.Create();
- Part := TList<Integer>.Create();
- for I := 0 to High(ToSplit) do
- if (Part.Count = 0) or (Part[Part.Count - 1] < ToSplit[I]) then
- Part.Add(ToSplit[I])
- else
- begin
- ListOfParts.Add(Part);
- Part := TList<Integer>.Create();
- Part.Add(ToSplit[I]);
- end;
- ListOfParts.Add(Part);
- SplitArray := ListOfParts;
- end;
- function MergeSort(ToSort: IntArray): IntArray;
- var
- ListOfParts: TListOfTList;
- NewPart: TList<Integer>;
- NewPartLength, I: Integer;
- SortedArray: IntArray;
- begin
- ListOfParts := SplitArray(ToSort);
- while (ListOfParts.Count > 1) do
- begin
- PrintPreSorted(ListOfParts);
- NewPart := TList<Integer>.Create();
- NewPartLength := ListOfParts[0].Count + ListOfParts[1].Count;
- for I := 0 to NewPartLength - 1 do
- if (ListOfParts[1].Count = 0) or
- ((ListOfParts[0].Count > 0) and
- (ListOfParts[0][0] < ListOfParts[1][0])) then
- begin
- NewPart.Add(ListOfParts[0][0]);
- ListOfParts[0].Delete(0);
- end
- else
- begin
- NewPart.Add(ListOfParts[1][0]);
- ListOfParts[1].Delete(0);
- end;
- ListOfParts.Delete(0);
- ListOfParts[0] := NewPart;
- end;
- PrintPreSorted(ListOfParts);
- SetLength(SortedArray, ListOfParts[0].Count - 1);
- for I := 0 to ListOfParts[0].Count - 1 do
- SortedArray[I] := ListOfParts[0][I];
- MergeSort := SortedArray;
- end;
- var
- UnSortedArray: IntArray;
- begin
- UnSortedArray := GetArray();
- InitFileAndConsole();
- MergeSort(UnSortedArray);
- PrintEndInfo();
- Readln;
- end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement