Advertisement
Vladislav8653

6.2 delphi

May 13th, 2023
177
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 14.64 KB | None | 0 0
  1. unit MainUnit;
  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.StdCtrls, Vcl.Grids, Vcl.ExtCtrls;
  8.  
  9. type
  10.   TForm1 = class(TForm)
  11.     Description1: TLabel;
  12.     InputM: TEdit;
  13.     InputN: TEdit;
  14.     Create: TButton;
  15.     InfoM: TLabel;
  16.     InfoN: TLabel;
  17.     Matrix: TStringGrid;
  18.     Description2: TLabel;
  19.     Help: TLabel;
  20.     ElementA: TButton;
  21.     ElementB: TButton;
  22.     MaxPath: TButton;
  23.     Timer1: TTimer;
  24.     procedure InputMKeyPress(Sender: TObject; var Key: Char);
  25.     procedure InputNKeyPress(Sender: TObject; var Key: Char);
  26.     procedure InputMChange(Sender: TObject);
  27.     procedure InputNChange(Sender: TObject);
  28.     procedure CreateClick(Sender: TObject);
  29.     procedure MatrixKeyPress(Sender: TObject; var Key: Char);
  30.     procedure MatrixSetEditText(Sender: TObject; ACol, ARow: Integer;
  31.       const Value: string);
  32.     procedure ElementAClick(Sender: TObject);
  33.     procedure MatrixSelectCell(Sender: TObject; ACol, ARow: Integer;
  34.       var CanSelect: Boolean);
  35.     procedure ElementBClick(Sender: TObject);
  36.     procedure MaxPathClick(Sender: TObject);
  37.   private
  38.     { Private declarations }
  39.   public
  40.     { Public declarations }
  41.   end;
  42.  
  43. type
  44.     Elements = record
  45.       Elem : Integer;
  46.       I : Byte;
  47.     end;
  48.     VertexLabel = record
  49.       Vertex : Integer;
  50.       Labels : String[1];
  51.     end;
  52.     PList = ^TNode;
  53.     TNode = record
  54.         Next : PList;
  55.         Data : String;
  56.     end;
  57.     PListOfLists = ^TList;
  58.     TList = record
  59.         Next : PListOfLists;
  60.         Data : PList;
  61.     end;
  62. type
  63.     TMatrix = array of array of elements;
  64.     TAdjacencyMatrix = array of array of Byte;
  65.  
  66. var
  67.     Form1: TForm1;
  68.     Arr: TMatrix;
  69.     AdjacencyMatrix : TAdjacencyMatrix;
  70.     SelectA, SelectB : Boolean;
  71.     I1, J1, I2, J2 : Integer;
  72.     VertexLabels : Array of VertexLabel;
  73.  
  74. implementation
  75.  
  76. {$R *.dfm}
  77.  
  78. procedure TForm1.CreateClick(Sender: TObject);
  79. var
  80.     M, N : Integer;
  81.     IsCorrect : Boolean;
  82. begin
  83.     IsCorrect := True;
  84.     try
  85.         M := StrToInt(InputM.Text);
  86.     except
  87.         IsCorrect := False;
  88.         MessageBox(Form1.Handle, Pchar('Проверьте поле для ввода кол-ва строк матрицы.'), 'Ошибка', MB_ICONSTOP);
  89.     end;
  90.     If IsCorrect then
  91.     begin
  92.         try
  93.             N := StrToInt(InputN.Text);
  94.         except
  95.             IsCorrect := False;
  96.             MessageBox(Form1.Handle, Pchar('Проверьте поле для ввода кол-ва столбцов матрицы.'), 'Ошибка', MB_ICONSTOP);
  97.         end;    
  98.     end;
  99.     If IsCorrect then
  100.     begin
  101.         SetLength(Arr, M, N);
  102.         Matrix.ColCount := N;
  103.         Matrix.RowCount := M;
  104.         Matrix.Visible := True;    
  105.     end;
  106. end;
  107.  
  108. procedure TForm1.ElementAClick(Sender: TObject);
  109. Var
  110.     Str : String;
  111. begin
  112.     Help.Visible := True;
  113.     SelectA := True;
  114.     Str := Help.Caption;
  115. end;
  116.  
  117. procedure TForm1.ElementBClick(Sender: TObject);
  118. begin
  119.     Help.Visible := True;
  120.     SelectB := True;
  121. end;
  122.  
  123. procedure TForm1.InputMChange(Sender: TObject);
  124. Const
  125.     STR1 = 'Элемент a';
  126.     STR2 = 'Элемент b';
  127. Var
  128.     I, J: Integer;
  129. begin
  130.     If (Length(InputM.Text) = 0) or (Length(InputN.Text) = 0)  then
  131.         Create.Enabled := False
  132.     else
  133.         Create.Enabled := True;
  134.     For I := 0 to Matrix.ColCount - 1 do
  135.         For J := 0 to Matrix.RowCount - 1 do
  136.             Matrix.Cells[I, J] := '';
  137.  
  138.     ElementA.Visible := False;
  139.     ElementB.Visible := False;
  140.     ElementA.Caption := STR1;
  141.     ElementB.Caption := STR2;
  142.     Help.Visible := False;
  143.     MaxPath.Visible := False;
  144.     Matrix.Options := Matrix.Options+[GoEditing];
  145. end;
  146.  
  147. procedure TForm1.InputMKeyPress(Sender: TObject; var Key: Char);
  148. begin
  149.     If (Key = #13) and (Create.Enabled) then
  150.         Create.Click;
  151.     If (Not(Key In ['1'..'5', #08, #46])) Then
  152.         Key := #0;
  153.     If Key = '.' then
  154.         Key := Char(0);
  155. end;
  156.  
  157. procedure TForm1.InputNChange(Sender: TObject);
  158. Const
  159.     STR1 = 'Элемент a';
  160.     STR2 = 'Элемент b';
  161. Var
  162.     I, J: Integer;
  163. begin
  164.     If (Length(InputM.Text) = 0) or (Length(InputN.Text) = 0)  then
  165.         Create.Enabled := False
  166.     else
  167.         Create.Enabled := True;
  168.     For I := 0 to Matrix.ColCount - 1 do
  169.         For J := 0 to Matrix.RowCount - 1 do
  170.             Matrix.Cells[I, J] := '';
  171.  
  172.     ElementA.Visible := False;
  173.     ElementB.Visible := False;
  174.     ElementA.Caption := STR1;
  175.     ElementB.Caption := STR2;
  176.     Help.Visible := False;
  177.     MaxPath.Visible := False;
  178.     Matrix.Options := Matrix.Options+[GoEditing];    
  179. end;
  180.  
  181. procedure TForm1.InputNKeyPress(Sender: TObject; var Key: Char);
  182. begin
  183.     If (Key = #13) and (Create.Enabled) then
  184.         Create.Click;
  185.     If (Not(Key In ['1'..'5', #08, #46])) Then
  186.         Key := #0;
  187.     If Key = '.' then
  188.         Key := Char(0);
  189. end;
  190.  
  191. procedure TForm1.MatrixKeyPress(Sender: TObject; var Key: Char);
  192. Var
  193.     I, J: Integer;
  194.     IsCorrect : Boolean;
  195. begin
  196.     If (Not(Key In ['0'..'9', #08, #46, '-'])) Then
  197.         Key := #0;
  198.     If Key = '.' then
  199.         Key := Char(0);    
  200.     With Sender As TStringGrid Do
  201.     Begin
  202.         If (Length(Matrix.Cells[Col, Row]) > 2) then
  203.             If (Not(Key In [#08, #46])) Then
  204.                 Key := #0;
  205.         If (Length(Matrix.Cells[Col, Row]) > 0) and (Key = '-')  then
  206.             Key := #0;
  207.     End;
  208. end;
  209.  
  210. procedure TForm1.MatrixSelectCell(Sender: TObject; ACol, ARow: Integer;
  211.   var CanSelect: Boolean);
  212. Const
  213.     STR1 = 'Элемент a';
  214.     STR2 = 'Элемент b';
  215. begin
  216.     If SelectA then
  217.     begin
  218.         I1 := ACol;
  219.         J1 := ARow;
  220.         ElementA.Caption := STR1 + ' [' + IntToStr(I1 + 1) + ', ' + IntToStr(J1 + 1) + ']';
  221.         SelectA := False;
  222.         Matrix.Options := Matrix.Options-[GoEditing];
  223.     end;
  224.     If SelectB then
  225.     begin
  226.         I2 := ACol;
  227.         J2 := ARow;  
  228.         ElementB.Caption := STR2 + ' [' + IntToStr(I2 + 1) + ', ' + IntToStr(J2 + 1) + ']';
  229.         SelectB := False;
  230.         Matrix.Options := Matrix.Options-[GoEditing];
  231.     end;
  232.     If (ElementA.Caption <> STR1) and (ElementB.Caption <> STR2) then
  233.         MaxPath.Visible := True;
  234. end;
  235.  
  236. procedure TForm1.MatrixSetEditText(Sender: TObject; ACol, ARow: Integer;
  237.   const Value: string);
  238. Var
  239.     I, J : Integer;
  240.     IsCorrect : Boolean;
  241. begin
  242.     IsCorrect := True;
  243.     For I := 0 to Matrix.ColCount  - 1 do
  244.         For J := 0 to Matrix.RowCount - 1 do
  245.             If (Length(Matrix.Cells[I, J]) = 0) Then
  246.             begin
  247.                 ElementA.Visible := False;
  248.                 ElementB.Visible := False;
  249.                 IsCorrect := False;
  250.                 Break;
  251.             end;
  252.     If IsCorrect then
  253.     begin
  254.         ElementA.Visible := True;
  255.         ElementB.Visible := True;
  256.     end;
  257.    
  258. end;
  259.  
  260. procedure TransformMatrixToAdjacencyMatrix(Arr: TMatrix; N, M: Integer);
  261. Const
  262.     ONE: Byte = 1;
  263. Var
  264.     I, J: Integer;
  265. begin
  266.     SetLength(AdjacencyMatrix, N * M, N * M);
  267.     For I := 0 to M-1 do
  268.     begin
  269.         For J := 0 to N-1 do
  270.         begin
  271.             if (I+1 < M) then
  272.             begin
  273.                 AdjacencyMatrix[Arr[I][J].I - 1][Arr[I+1][J].I - 1] := ONE;
  274.                 AdjacencyMatrix[Arr[I+1][J].I - 1][Arr[I][J].I - 1] := ONE;
  275.             end;
  276.             if (I > 0) then
  277.             begin
  278.                 AdjacencyMatrix[Arr[I][J].I - 1][Arr[I-1][J].I - 1] := ONE;
  279.                 AdjacencyMatrix[Arr[I-1][J].I - 1][Arr[I][J].I - 1] := ONE;
  280.             end;
  281.             if (J+1 < N) then
  282.             begin
  283.                 AdjacencyMatrix[Arr[I][J].I - 1][Arr[I][J+1].I - 1] := ONE;
  284.                 AdjacencyMatrix[Arr[I][J+1].I - 1][Arr[I][J].I - 1] := ONE;
  285.             end;
  286.             if (J > 0) then
  287.             begin
  288.                 AdjacencyMatrix[Arr[I][J].I - 1][Arr[I][J-1].I - 1] := ONE;
  289.                 AdjacencyMatrix[Arr[I][J-1].I - 1][Arr[I][J].I - 1] := ONE;
  290.             end;
  291.         end;
  292.     end;
  293. end;
  294.  
  295. function IsContains (CurrentPath : PList; Str : String) : Boolean;
  296. Var                                                    // надо проследить поведение этой функции
  297.     Contains : Boolean;
  298. Begin
  299.     Contains := False;
  300.     While CurrentPath <> nil Do
  301.     begin
  302.         If CurrentPath.Data = Str then
  303.         begin
  304.             Contains := True;
  305.             CurrentPath := nil;
  306.         end
  307.         else
  308.         begin
  309.             CurrentPath := CurrentPath.Next;
  310.         end;
  311.     end;
  312.     IsContains := Contains;
  313. End;
  314.  
  315. procedure AddPathInAllPaths (var AllPaths : PListOfLists; List : PList);
  316. Var
  317.     Head, NewItem : PListOfLists;
  318. Begin
  319.     New(NewItem);
  320.     NewItem^.Data := List;
  321.     NewItem^.Next := nil;
  322.     if AllPaths = nil then
  323.         AllPaths := NewItem
  324.     else
  325.     begin
  326.         Head := AllPaths;
  327.         while Head^.Next <> nil Do
  328.             Head := Head^.Next;
  329.         Head^.Next := NewItem;
  330.     end;
  331. End;
  332.  
  333. procedure AddinList(var List: PList; Str: String);
  334. var
  335.     NewItem, Head: PList;
  336. begin
  337.     New(NewItem);
  338.     NewItem^.Data := Str;
  339.     NewItem^.Next := nil;
  340.     if List = nil then
  341.         List := NewItem
  342.     else
  343.     begin
  344.         Head := List;
  345.         while Head^.Next <> nil do
  346.             Head := Head^.Next;
  347.         Head^.Next := NewItem;
  348.     end;
  349. end;
  350.  
  351.  
  352.  
  353. procedure RemoveFromList(var List: PList);
  354. var
  355.     Head, Prev: PList;
  356. begin
  357.     Head := List;
  358.     Prev := nil;
  359.     while Head^.Next <> nil do
  360.     begin
  361.         Prev := Head;
  362.         Head := Head^.Next;
  363.     end;
  364.     if Prev = nil then
  365.         List := nil
  366.     else
  367.         Prev^.Next := nil;
  368.     Dispose(Head);
  369. end;
  370.  
  371.  
  372. procedure AllPathsDFS (CurrentIndex, FinishIndex : Integer; CurrentPath : PList; var AllPaths : PListOfLists);
  373. Var
  374.     I : Integer;
  375. begin
  376.     If (CurrentIndex = FinishIndex) then
  377.     Begin
  378.         AddPathInAllPaths(AllPaths, CurrentPath);
  379.     End
  380.     else
  381.     begin
  382.         For I := Low(AdjacencyMatrix[CurrentIndex]) To High(AdjacencyMatrix[CurrentIndex]) Do
  383.         begin
  384.             If (AdjacencyMatrix[CurrentIndex][I] = 1) and Not(IsContains(CurrentPath, VertexLabels[I].Labels)) then
  385.             begin
  386.                 AddinList(CurrentPath, Vertexlabels[I].Labels);
  387.                 AllPathsDFS(I, FinishIndex, CurrentPath, AllPaths);
  388.                 //RemoveFromList(CurrentPath);
  389.             end;        
  390.         end;        
  391.     end;
  392. end;
  393.  
  394. function GetAllPaths(Start, Finish : String) : PListOfLists;
  395. Var
  396.     StartIndex, EndIndex, I : Integer;
  397.     AllPaths : PListOfLists;
  398.     CurrentPath : PList;
  399.     IsCorrect : Boolean;
  400. Begin
  401.     StartIndex := -1;
  402.     EndIndex := -1;
  403.     For I := Low(VertexLabels) To High(VertexLabels) do
  404.     begin
  405.         If Start = VertexLabels[I].Labels then
  406.             StartIndex := I;
  407.         If Finish = VertexLabels[I].Labels then
  408.             EndIndex := I;
  409.     end;
  410.     IsCorrect := True;
  411.     If (StartIndex = -1) or (EndIndex = -1) then
  412.     Begin
  413.         IsCorrect := False;
  414.         GetAllPaths := AllPaths;
  415.     End;
  416.     AllPaths := nil;
  417.     CurrentPath := nil;
  418.     If IsCorrect then
  419.     Begin
  420.         AddinList(CurrentPath, Start);
  421.         AllPathsDFS(StartIndex, EndIndex, CurrentPath, AllPaths);
  422.         GetAllPaths := AllPaths;
  423.     End;
  424. End;
  425.  
  426. function FindSum (List : PList) : Integer;
  427. Var
  428.     Sum, I : Integer;
  429. Begin
  430.     Sum := 0;
  431.     For I := Low(VertexLabels) To High(VertexLabels) Do
  432.     begin
  433.         if IsContains(List, VertexLabels[I].Labels) then
  434.             Sum := Sum + VertexLabels[I].Vertex;
  435.     end;
  436.     FindSum := Sum;
  437. End;
  438.  
  439. function ShowMaxPaths(List : PList) : String;
  440. Var
  441.     Str : String;
  442. Begin
  443.     while List <> nil do
  444.     begin
  445.         Str := Str + List.Data + ' ';
  446.         List := List.Next;
  447.     end;
  448.     ShowMaxPaths := Str;
  449. End;
  450.  
  451. function FindPaths(Start, Finish : String) : String;
  452. Var
  453.     Sum, Max, I: Integer;
  454.     Str : String;
  455.     Head, AllPaths : PListOfLists;
  456. Begin
  457.     Max := 0;
  458.     AllPaths := GetAllPaths(Start, Finish);
  459.     Head := AllPaths;
  460.     While Head <> nil Do
  461.     begin                             // обособить в функцию
  462.         Sum := FindSum(Head.Data);
  463.         If Sum > Max then
  464.             Max := Sum;
  465.         Head := Head.Next;
  466.     end;
  467.  
  468.     While AllPaths <> nil Do
  469.     begin
  470.         If Max = FindSum(AllPaths.Data) then
  471.             Str := Str + ShowMaxPaths(AllPaths.Data) + #13#10;
  472.         AllPaths := AllPaths.Next;
  473.     end;
  474.     //это все для примера, так как после этого не будет AllPaths
  475.     FindPaths := Str;
  476. End;
  477.  
  478.  
  479. procedure TForm1.MaxPathClick(Sender: TObject;);
  480. Var
  481.     I, J, K : Integer;
  482.     IsCorrect : Boolean;
  483.     Vertex : Char;
  484.     Start, Finish : String[1];
  485.     Index : Byte;
  486. Const
  487.     STR1 = 'Элемент a';
  488.     STR2 = 'Элемент b';
  489. begin
  490.     IsCorrect := True;
  491.     Index := 1;
  492.     If IsCorrect then
  493.     begin
  494.         try
  495.         For I := 0 to Matrix.ColCount - 1 do
  496.             For J := 0 to Matrix.RowCount - 1 do
  497.             Begin
  498.                 Arr[J, I].Elem := StrToInt(Matrix.Cells[I,J]);
  499.                 Arr[J, I].I := Index;
  500.                 Inc(Index);
  501.             End;
  502.         except
  503.             IsCorrect := False;
  504.             MessageBox(Form1.Handle, Pchar('Проверьте содержимое матрицы. В клеточках должны быть только целочисленные значения.'), 'Ошибка', MB_ICONSTOP);
  505.             ElementA.Visible := False;
  506.             ElementB.Visible := False;
  507.             ElementA.Caption := STR1;
  508.             ElementB.Caption := STR2;
  509.             Help.Visible := False;
  510.             MaxPath.Visible := False;
  511.             Matrix.Options := Matrix.Options+[GoEditing];    
  512.         end;
  513.     end;
  514.     If IsCorrect then
  515.     begin
  516.         TransformMatrixToAdjacencyMatrix(Arr, Matrix.ColCount, Matrix.RowCount);
  517.         K := 0;
  518.         Vertex := 'A';
  519.         SetLength(VertexLabels, Matrix.RowCount * Matrix.ColCount);
  520.         For I := 0 to Matrix.ColCount - 1 do
  521.             For J := 0 to Matrix.RowCount - 1 do
  522.             begin
  523.                 VertexLabels[K].Vertex := Arr[J, I].Elem;
  524.                 VertexLabels[K].Labels := Vertex;
  525.                 If (I = I1) and (J = J1) then
  526.                     Start := Vertex;
  527.                 If (I = I2) and (J = J2) then
  528.                     Finish := Vertex;
  529.                 Vertex := Chr(Ord(Vertex) + 1);
  530.                 Inc(K);
  531.             end;
  532.         Description1.Caption := FindPaths(Start, Finish);
  533.         Description2.Visible := False;  //это для примера!
  534.     end;
  535. end;
  536.  
  537. end.
  538.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement