Vanilla_Fury

laba_5_1_del

Mar 14th, 2021
282
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 16.29 KB | None | 0 0
  1. unit laba_5_1_f1;
  2.  
  3. interface
  4.  
  5. uses
  6.   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  7.   Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Menus, Vcl.StdCtrls, System.RegularExpressions,
  8.   Vcl.ExtCtrls, Vcl.ComCtrls, System.UITypes;
  9.  
  10. type
  11.     TArrStr = Array of String;
  12.     TArrInt = Array of Integer;
  13.  
  14.     PNode = ^TNode;
  15.     TNode = Record
  16.         Number: Integer;
  17.         NextNode: PNode;
  18.     End;
  19.     TMyList = Record
  20.         HeadNode: PNode;
  21.         ListSize: Integer;
  22.     End;
  23.  
  24.     TFormMain = class(TForm)
  25.     MainMenu1: TMainMenu;
  26.     NHelp: TMenuItem;
  27.     NAuthor: TMenuItem;
  28.     OpenDialog1: TOpenDialog;
  29.     NFile: TMenuItem;
  30.     NOpen: TMenuItem;
  31.     NSaveAs: TMenuItem;
  32.     SaveDialog1: TSaveDialog;
  33.     NSave: TMenuItem;
  34.     NTask: TMenuItem;
  35.     LabelToMeasureScreenOfUser: TLabel;
  36.     MemoInputList: TMemo;
  37.     MemoOutput: TMemo;
  38.     ButtonAccept: TButton;
  39.     MemoInputArray: TMemo;
  40.     LabelList: TLabel;
  41.     LabelArray: TLabel;
  42.     LabelAnswer: TLabel;
  43.     BalloonHint1: TBalloonHint;
  44.     procedure NAuthorClick(Sender: TObject);
  45.     procedure NOpenClick(Sender: TObject);
  46.     procedure NSaveAsClick(Sender: TObject);
  47.     procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  48.     procedure FormCreate(Sender: TObject);
  49.     procedure NSaveClick(Sender: TObject);
  50.     procedure NTaskClick(Sender: TObject);
  51.     function MultPixels(PixQuant: Integer) : Integer;
  52.     procedure MemoInputListChange(Sender: TObject);
  53.     procedure ButtonAcceptClick(Sender: TObject);
  54.     procedure AddNodeInList(var List: TMyList; Number: Integer);
  55.     procedure SwapNodesInList(Node1, Node2: PNode);
  56.     function FindNodeInList(var List: TMyList; Number: Integer) : PNode;
  57.     function ConvertListIntoArray(var List: TMyList) : TArrInt;
  58.     procedure ComputeAndOutputAnswer(List: TMyList; Arr: TArrInt);
  59.  
  60.     private
  61.         MultPix: Single;
  62.         StrFile: String;
  63.         IsSaved: Boolean;
  64.     public
  65.  
  66.     end;
  67.  
  68. const
  69.     RegExForNumber = '[1-9]\d{0,2}';
  70.     CaptionHereWillBeAnswer = 'Здесь будет ответ';
  71.  
  72. var
  73.     FormMain: TFormMain;
  74.  
  75. implementation
  76. {$R *.dfm}
  77.  
  78. function FindRegEx(SInput, StrRegEx: String; StrIfNothingFound: String = '') : TArrStr; forward;
  79.  
  80.  
  81. //******************************************************************************
  82. // Операции над списком
  83.  
  84. procedure TFormMain.AddNodeInList(var List: TMyList; Number: Integer);
  85. var
  86.     NewNode, CurrentNode: PNode;
  87.     ProcessIsNotDone: Boolean;
  88.  
  89. begin
  90.     New(NewNode);
  91.     with List do
  92.     begin
  93.         if HeadNode = nil then
  94.         begin
  95.             HeadNode := NewNode;
  96.             ListSize := 1;
  97.         end
  98.         else
  99.         begin
  100.             ProcessIsNotDone := True;
  101.             CurrentNode := HeadNode;
  102.             while (CurrentNode <> nil) and ProcessIsNotDone do
  103.             begin
  104.                 if CurrentNode.Number = Number then
  105.                     ProcessIsNotDone := False
  106.                 else
  107.                     if CurrentNode.NextNode = nil then
  108.                     begin
  109.                         CurrentNode.NextNode := NewNode;
  110.                         Inc(ListSize);
  111.                         ProcessIsNotDone := False;
  112.                     end
  113.                     else
  114.                         CurrentNode := CurrentNode.NextNode;
  115.             end;
  116.         end;
  117.  
  118.         NewNode.Number := Number;
  119.         NewNode.NextNode := nil;
  120.     end;
  121. end;
  122.  
  123. procedure TFormMain.SwapNodesInList(Node1, Node2: PNode);
  124. var
  125.     NumberTemp: Integer;
  126.  
  127. begin
  128.     NumberTemp := Node1.Number;
  129.     Node1.Number := Node2.Number;
  130.     Node2.Number := NumberTemp;
  131. end;
  132.  
  133. function TFormMain.FindNodeInList(var List: TMyList; Number: Integer) : PNode;
  134. var
  135.     CurrentNode: PNode;
  136.     ProcessIsNotDone: Boolean;
  137.  
  138. begin
  139.     CurrentNode := List.HeadNode;
  140.     ProcessIsNotDone := True;
  141.     while (CurrentNode <> nil) and ProcessIsNotDone do
  142.     begin
  143.         if CurrentNode.Number = Number then
  144.             ProcessIsNotDone := False
  145.         else
  146.             CurrentNode := CurrentNode.NextNode;
  147.     end;
  148.  
  149.     Result := CurrentNode;
  150. end;
  151.  
  152. function TFormMain.ConvertListIntoArray(var List: TMyList) : TArrInt;
  153. var
  154.     QuantityOfElem: Integer;
  155.     CurrentNode: PNode;
  156.     ArrOutput: TArrInt;
  157.  
  158. begin
  159.     SetLength(ArrOutput, 8);
  160.     QuantityOfElem := 0;
  161.  
  162.     CurrentNode := List.HeadNode;
  163.     while CurrentNode <> nil do
  164.     begin
  165.         Inc(QuantityOfElem);
  166.         if QuantityOfElem > Length(ArrOutput) then
  167.             SetLength(ArrOutput, Round(Length(ArrOutput) * 1.5));
  168.  
  169.         ArrOutput[QuantityOfElem - 1] := CurrentNode.Number;
  170.         CurrentNode := CurrentNode.NextNode;
  171.     end;
  172.     SetLength(ArrOutput, QuantityOfElem);
  173.     Result := ArrOutput;
  174. end;
  175.  
  176.  
  177. //******************************************************************************
  178. // Ввод данных
  179.  
  180. procedure TFormMain.MemoInputListChange(Sender: TObject);
  181. var
  182.     Strs: TArrStr;
  183.     StrOneNumber, TextTemp: String;
  184.     i, SelStartTemp: Integer;
  185.     HasSpaceAtTheEnd: Boolean;
  186.     Point: TPoint;
  187.  
  188. begin
  189.     TextTemp := '';
  190.     with Sender as TMemo do
  191.     begin
  192.         HasSpaceAtTheEnd := (Length(Text) > 0) and
  193.             ((Text[High(Text)] = ' ') or (Text[High(Text)] = #10));
  194.         SelStartTemp := SelStart;
  195.         Strs := FindRegEx(Text, '\d+');
  196.  
  197.         if Length(Strs) > 999 then
  198.         begin
  199.             SetLength(Strs, 999);
  200.             BalloonHint1.Title := 'Предупреждение';
  201.             BalloonHint1.Description := 'Максисальное количество чисел - 999';
  202.             Point.X := Round(Width * 2 / 3);
  203.             Point.Y := Height;
  204.             Balloonhint1.ShowHint(ClientToScreen(Point));
  205.         end;
  206.  
  207.         for i := 0 to High(Strs) do
  208.         begin
  209.             StrOneNumber := FindRegEx(Strs[i], RegExForNumber)[0];
  210.             TextTemp := TextTemp + StrOneNumber;
  211.             if i <> High(Strs) then
  212.                 TextTemp := TextTemp + ' ';
  213.         end;
  214.  
  215.         if HasSpaceAtTheEnd then
  216.                 TextTemp := TextTemp + ' ';
  217.  
  218.         if Text <> TextTemp then
  219.         begin
  220.             if Text <> TextTemp + ' ' then
  221.             begin
  222.                 BalloonHint1.Title := 'Предупреждение';
  223.                 BalloonHint1.Description := 'Разрешены только целые числа от 1 до 999.';
  224.                 Point.X := Round(Width * 2 / 3);
  225.                 Point.Y := Height;
  226.                 Balloonhint1.ShowHint(ClientToScreen(Point));
  227.             end;
  228.  
  229.             Text := TextTemp;
  230.             SelStart := SelStartTemp;
  231.         end;
  232.     end;
  233.  
  234.     if (MemoInputList.Text <> '') and (MemoInputArray.Text <> '') then
  235.         ButtonAccept.Enabled := True
  236.     else
  237.         ButtonAccept.Enabled := False;
  238.  
  239.     NSaveAs.Enabled := False;
  240.     NSave.Enabled := False;
  241.  
  242.     MemoOutput.Text := CaptionHereWillBeAnswer;
  243. end;
  244.  
  245. procedure TFormMain.ButtonAcceptClick(Sender: TObject);
  246. var
  247.     StrsMemoList, StrsMemoArray: TArrStr;
  248.     Str: String;
  249.     MyList, MyList2: TMyList;
  250.     Arr: TArrInt;
  251.     i, Number: Integer;
  252.     IsCorrect: Boolean;
  253.     Current: PNode;
  254.  
  255. begin
  256.     IsCorrect := True;
  257.  
  258.     StrsMemoList := FindRegEx(MemoInputList.Text, RegExForNumber);
  259.     StrsMemoArray := FindRegEx(MemoInputArray.Text, RegExForNumber);
  260.  
  261.     MyList.HeadNode := nil;
  262.     for Str in StrsMemoList do
  263.         AddNodeInList(MyList, StrToInt(Str));
  264.  
  265.     MyList2.HeadNode := nil;
  266.     for Str in StrsMemoArray do
  267.         AddNodeInList(MyList2, StrToInt(Str));
  268.  
  269.     Arr := ConvertListIntoArray(MyList2);
  270.  
  271.     MemoInputArray.Clear();
  272.     for Number in Arr do
  273.         With MemoInputArray do
  274.             Text := Text + IntToStr(Number) + ' ';
  275.     MemoInputList.Clear();
  276.     Current := MyList.HeadNode;
  277.     while Current <> nil do
  278.     begin
  279.         With MemoInputList do
  280.             Text := Text + IntToStr(Current.Number) + ' ';
  281.         Current := Current.NextNode;
  282.     end;
  283.  
  284.     if Length(Arr) <> MyList.ListSize then
  285.     begin
  286.         ShowMessage('Числа в массиве не соответствуют реальному размеру списка');
  287.         IsCorrect := False;
  288.     end;
  289.  
  290.     i := 0;
  291.     while IsCorrect and (i < Length(Arr)) do
  292.     begin
  293.         if Arr[i] > MyList.ListSize then
  294.         begin
  295.             ShowMessage('Числа в массиве не соответствуют реальному размеру списка');
  296.             IsCorrect := False;
  297.         end
  298.         else
  299.             Inc(i);
  300.     end;
  301.  
  302.     if IsCorrect then
  303.     begin
  304.         ComputeAndOutputAnswer(MyList, Arr);
  305.         NSaveAs.Enabled := True;
  306.         NSave.Enabled := StrFile <> '';
  307.     end;
  308. end;
  309.  
  310. procedure TFormMain.ComputeAndOutputAnswer(List: TMyList; Arr: TArrInt);
  311. var
  312.     Current, ToSwapWith: PNode;
  313.     SerNum, i, j: Integer;
  314.     ListOut: TMyList;
  315.  
  316. begin
  317.     MemoOutput.Clear();
  318.     ListOut.HeadNode := nil;
  319.  
  320.     for SerNum in Arr do
  321.     begin
  322.         Current := List.HeadNode;
  323.         i := 1;
  324.         while i < SerNum do
  325.         begin
  326.             Current := Current.NextNode;
  327.             Inc(i);
  328.         end;
  329.  
  330.         AddNodeInList(ListOut, Current.Number);
  331.     end;
  332.  
  333.     Current := ListOut.HeadNode;
  334.     while Current <> nil do
  335.     begin
  336.         With MemoOutput do
  337.             Text := Text + IntToStr(Current.Number) + ' ';
  338.         Current := Current.NextNode;
  339.     end;
  340. end;
  341.  
  342.  
  343. //******************************************************************************
  344. // Работа с файлами
  345.  
  346. procedure TFormMain.NOpenClick(Sender: TObject);
  347. const
  348.     ErrorDuringInputOccured = 'Возникла ошибка при открытии файла.' + #10#13 +
  349.                 'Пожалуйста, выберите файл нужного формата(.datgrad) с ' +
  350.                 'корректными данными.';
  351.  
  352. var
  353.     FileInput : TextFile;
  354.     PathToFile, String1: String;
  355.  
  356. begin
  357.     if not IsSaved and (MessageDlg('Вы хотите сохранить текущие данные?' +
  358.         #10#13 + 'Иначе после открытия файла текущие записи будут удалены.',
  359.         mtConfirmation, [mbYes, mbNo], 0) = mrYes) then
  360.         NSaveClick(Self);
  361.  
  362.     if (IsSaved or (MessageDlg('Вы уверены, что хотите открыть другой файл?' + #10#13 +
  363.         'Все текущие записи будут удалены.', mtConfirmation, [mbYes, mbCancel], 0) = mrYes))
  364.         and OpenDialog1.Execute then
  365.     begin
  366.         PathToFile := OpenDialog1.FileName;
  367.         try
  368.             AssignFile(FileInput, PathToFile);
  369.             Reset(FileInput);
  370.  
  371.             Readln(FileInput, String1);
  372.             MemoInputList.Text := String1;
  373.             Readln(FileInput, String1);
  374.             MemoInputArray.Text := String1;
  375.  
  376.             CloseFile(FileInput);
  377.             ButtonAcceptClick(Self);
  378.         except
  379.             ShowMessage(ErrorDuringInputOccured);
  380.         end;
  381.     end;
  382. end;
  383.  
  384. procedure TFormMain.NSaveAsClick(Sender: TObject);
  385. var
  386.     FileOutput : TextFile;
  387.     StrFilePath: String;
  388.     ShouldNotRepeat: Boolean;
  389.     Point: TPoint;
  390.  
  391. begin
  392.     try
  393.         repeat
  394.             ShouldNotRepeat := True;
  395.             if SaveDialog1.Execute then
  396.             begin
  397.                 StrFilePath := SaveDialog1.FileName;
  398.                 StrFilePath := FindRegEx(StrFilePath, '.+\.txt', StrFilePath + '.txt')[0];
  399.  
  400.                 if FileExists(StrFilePath) then
  401.                     if MessageDlg('Такой файл уже существует.' +
  402.                         #10#13 + 'Вы хотите перезаписать файл? Это действие невозможно отменить.',
  403.                         mtConfirmation, [mbYes, mbNo], 0) = mrYes then
  404.                         ShouldNotRepeat := True
  405.                     else
  406.                         ShouldNotRepeat := False
  407.                 else
  408.                     ShouldNotRepeat := True;
  409.  
  410.                 if ShouldNotRepeat then
  411.                 begin
  412.                     AssignFile(FileOutput, StrFilePath);
  413.                     Rewrite(FileOutput);
  414.  
  415.                     Write(FileOutput, 'Введённый список:' + #10#13
  416.                         + MemoInputList.Text + #10#13 + 'Введённый массив:'
  417.                         + #10#13 + MemoInputArray.Text + #10#13 + 'Ответ:'
  418.                         + #10#13 + MemoOutput.Text + #10#13);
  419.  
  420.                     CloseFile(FileOutput);
  421.                     IsSaved := True;
  422.                     BalloonHint1.Title := 'Готово';
  423.                     BalloonHint1.Description := 'Ответ успешно записан в файл.';
  424.                     Point.X := Round(MemoOutput.Left + MemoOutput.Width * 2 / 3);
  425.                     Point.Y := MemoOutput.Top + MemoOutput.Height;
  426.                     Balloonhint1.ShowHint(ClientToScreen(Point));
  427.  
  428.  
  429.                     NSave.Enabled := True;
  430.                     StrFile := StrFilePath;
  431.                 end;
  432.             end;
  433.         until ShouldNotRepeat;
  434.     except
  435.        ShowMessage('Не удается открыть файл для вывода данных или записать в него данные.');
  436.     end;
  437. end;
  438.  
  439. procedure TFormMain.NSaveClick(Sender: TObject);
  440. var
  441.     FileOutput : TextFile;
  442.  
  443. begin
  444.     if MessageDlg('Вы хотите перезаписать файл "' + StrFile + '"?' + #10#13 +
  445.         'Это действие невозможно отменить.', mtConfirmation, [mbYes, mbNo], 0) = mrYes then
  446.         if FileExists(StrFile) then
  447.         begin
  448.             AssignFile(FileOutput, StrFile);
  449.             Rewrite(FileOutput);
  450.  
  451.             Write(FileOutput, 'Введённый список:' + #10#13
  452.                 + MemoInputList.Text + #10#13 + 'Введённый массив:' + #10#13
  453.                 + MemoInputArray.Text + #10#13 + 'Ответ:'
  454.                 + #10#13 + MemoOutput.Text + #10#13);
  455.  
  456.             CloseFile(FileOutput);
  457.             IsSaved := True;
  458.         end
  459.         else
  460.         begin
  461.             ShowMessage('Этого файла уже не существует.');
  462.             StrFile := '';
  463.             NSave.Enabled := False;
  464.             NSaveAsClick(Self);
  465.         end;
  466. end;
  467.  
  468.  
  469. //******************************************************************************
  470. // Form Create
  471.  
  472. procedure TFormMain.FormCreate(Sender: TObject);
  473. begin
  474.     MultPix := LabelToMeasureScreenOfUser.Width / 100;
  475.     StrFile := '';
  476.     IsSaved := True;
  477.     MemoOutput.Text := CaptionHereWillBeAnswer;
  478. end;
  479.  
  480. //******************************************************************************
  481. // Прочее
  482.  
  483. procedure TFormMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  484. begin
  485.     CanClose := IsSaved or (MessageDlg('Вы уверены, что хотите выйти из программы?' +
  486.         #10#13 + 'Все несохранённые данные будут утеряны.',
  487.         mtConfirmation, [mbYes, mbNo], 0) = mrYes);
  488. end;
  489.  
  490. procedure TFormMain.NAuthorClick(Sender: TObject);
  491. begin
  492.     ShowMessage('Панев Александр, гр. 051007' + #10#13 + 'Минск, 2021');
  493. end;
  494.  
  495. procedure TFormMain.NTaskClick(Sender: TObject);
  496. begin
  497.     ShowMessage('Дан неупорядоченный линейный односвязный список и массив, ' +
  498.     'содержащий номера соответствующих элементов в упорядоченном списке. ' +
  499.     'Перестроить данный список в соответствии с номерами, заданными массивом.');
  500. end;
  501.  
  502. function FindRegEx(SInput, StrRegEx: String; StrIfNothingFound: String = '') : TArrStr;
  503. var
  504.     ArrStr: TArrStr;
  505.     RegEx: TRegEx;
  506.     MatchCollection: TMatchCollection;
  507.     i: Integer;
  508. begin
  509.     RegEx := TRegEx.Create(StrRegEx);
  510.     MatchCollection := RegEx.Matches(SInput);
  511.     SetLength(ArrStr, MatchCollection.Count);
  512.     for i := 0 to MatchCollection.Count - 1 do
  513.         ArrStr[i] := MatchCollection.Item[i].Value;
  514.  
  515.     if (Length(ArrStr) < 1) then
  516.         ArrStr := [StrIfNothingFound];
  517.     Result := ArrStr;
  518. end;
  519.  
  520. function TFormMain.MultPixels(PixQuant: Integer) : Integer;
  521. begin
  522.     Result := Round(PixQuant * MultPix);
  523. end;
  524.  
  525. end.
Advertisement
Add Comment
Please, Sign In to add comment