Vanilla_Fury

laba_7_1_del

Jun 9th, 2021
436
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.41 KB | None | 0 0
  1. unit Main;
  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.Menus, Vcl.Grids, Vector;
  8.  
  9. type
  10. TMatrix = Array of Array of Integer;
  11. TMyArray = class(TArray<Integer>)
  12. end;
  13. TVector = class(TArray<TMyArray>)
  14. end;
  15. TVectorCopy = Array of TMyArray;
  16.  
  17. TMainForm = class(TForm)
  18. sgMatrix: TStringGrid;
  19. Task: TLabel;
  20. MainMenu: TMainMenu;
  21. About: TMenuItem;
  22. FileMenu: TMenuItem;
  23. OpenFromFileMenu: TMenuItem;
  24. SaveToFileMenu: TMenuItem;
  25. OpenFromFile: TOpenDialog;
  26. SaveToFile: TSaveDialog;
  27. Proces: TButton;
  28. NumOfNodesLabel: TLabel;
  29. NumOfColsLabel: TLabel;
  30. NumOfRowsEdit: TEdit;
  31. NumOfColsEdit: TEdit;
  32. IncidentListMemo: TMemo;
  33. procedure sgMatrixKeyPress(Sender: TObject; var Key: Char);
  34. procedure NumOfRowsEditKeyPress(Sender: TObject; var Key: Char);
  35. procedure NumOfColsEditKeyPress(Sender: TObject; var Key: Char);
  36. procedure NumOfRowsEditChange(Sender: TObject);
  37. procedure NumOfColsEditChange(Sender: TObject);
  38. procedure OpenFromFileMenuClick(Sender: TObject);
  39. procedure SaveToFileMenuClick(Sender: TObject);
  40. procedure ProcesClick(Sender: TObject);
  41. procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  42.  
  43. procedure PrintIncidentList(IncidentList: TVector);
  44. function CheckMatrixValues(): Boolean;
  45. function CheckNumberOfLinkedNodes(): Boolean;
  46. function CheckOrientedEdges(): Boolean;
  47. function CheckLoopEdges(): Boolean;
  48.  
  49. procedure FormCreate(Sender: TObject);
  50. procedure FileMenuClick(Sender: TObject);
  51. procedure AboutClick(Sender: TObject);
  52. private
  53. { Private declarations }
  54. public
  55. { Public declarations }
  56. end;
  57.  
  58. var
  59. MainForm: TMainForm;
  60. IncidentMatrix: TMatrix;
  61.  
  62. implementation
  63.  
  64. {$R *.dfm}
  65.  
  66. type
  67. TFileState = (fsSomething, fsEmpty, fsMissing);
  68. TArray = Array of Byte;
  69.  
  70. procedure TMainForm.FileMenuClick(Sender: TObject);
  71. begin
  72. SaveToFileMenu.Enabled := not (IncidentListMemo.Lines.Count = 0);
  73. end;
  74.  
  75. procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  76. var
  77. WND: HWND;
  78. lpCaption, lpText: PChar;
  79. Tip: Integer;
  80. begin
  81. WND := MainForm.Handle;
  82. lpCaption := 'Выход';
  83. lpText := 'Вы уверены, что хотите выйти?';
  84. Tip := MB_YESNO + MB_ICONINFORMATION + MB_DEFBUTTON2;
  85. case MessageBox(WND, lpText, lpCaption, Tip) of
  86. IDYES : CanClose := True;
  87. IDNO : CanClose := False;
  88. end;
  89. end;
  90.  
  91. procedure TMainForm.FormCreate(Sender: TObject);
  92. begin
  93. IncidentListMemo.Clear();
  94. end;
  95.  
  96. procedure TMainForm.NumOfColsEditChange(Sender: TObject);
  97. var
  98. Length: Integer;
  99. I: Byte;
  100. begin
  101. if (NumOfColsEdit.Text <> '') then
  102. begin
  103. if (NumOfRowsEdit.Text <> '') then
  104. sgMatrix.Enabled := True
  105. else
  106. sgMatrix.Enabled := False;
  107. sgMatrix.ColCount := StrToInt(NumOfColsEdit.Text) + 1;
  108. sgMatrix.Width := (sgMatrix.DefaultColWidth + 2) * sgMatrix.ColCount;
  109. Length := sgMatrix.Left + sgMatrix.Width;
  110. if (Length > MainForm.ClientWidth) then
  111. MainForm.ClientWidth := Length + 20;
  112.  
  113. for I := sgMatrix.FixedCols to sgMatrix.ColCount - 1 do
  114. sgMatrix.Cells[i, 0] := 'r' + IntToStr(i);
  115. end;
  116. end;
  117.  
  118. procedure TMainForm.NumOfColsEditKeyPress(Sender: TObject; var Key: Char);
  119. begin
  120. if not (Key in ['1'..'9', #08]) then
  121. Key := #0;
  122. end;
  123.  
  124. procedure TMainForm.NumOfRowsEditChange(Sender: TObject);
  125. var
  126. Height: Integer;
  127. I: Byte;
  128. begin
  129. if (NumOfRowsEdit.Text <> '') then
  130. begin
  131. if (NumOfColsEdit.Text <> '') then
  132. sgMatrix.Enabled := True
  133. else
  134. sgMatrix.Enabled := False;
  135. sgMatrix.RowCount := StrToInt(NumOfRowsEdit.Text) + 1;
  136. sgMatrix.Height := (sgMatrix.DefaultRowHeight + 2) * sgMatrix.RowCount;
  137. Height := sgMatrix.Top + sgMatrix.Height;
  138. if (Height > MainForm.ClientHeight) then
  139. MainForm.ClientHeight := Height + 20;
  140.  
  141. for I := sgMatrix.FixedRows to sgMatrix.RowCount - 1 do
  142. sgMatrix.Cells[0, i] := IntToStr(i);
  143. end;
  144. end;
  145.  
  146. function GetMatrixFromFile(FileName: string; var IsCorrect: Boolean): TMatrix;
  147. var
  148. InputFile: TextFile;
  149. Matrix: TMatrix;
  150. NumOfRows, NumOfCols, I, J: Byte;
  151. begin
  152. IsCorrect := True;
  153. try
  154. if FileExists(FileName) then
  155. begin
  156. Assign(InputFile, FileName);
  157. Reset(InputFile);
  158. end
  159. else
  160. begin
  161. IsCorrect := False;
  162. Application.MessageBox('Файл не найден!','Ошибка',MB_ICONERROR);
  163. end;
  164. except
  165. IsCorrect := False;
  166. Application.MessageBox('Ошибка доступа к файлу!','Ошибка',MB_ICONERROR);
  167. end;
  168.  
  169. if (IsCorrect) then
  170. begin
  171. try
  172. Readln(InputFile, NumOfRows);
  173. except
  174. IsCorrect := False;
  175. end;
  176. if (NumOfRows < 1) or (NumOfRows > 9) then
  177. IsCorrect := False;
  178. end;
  179.  
  180. if (IsCorrect) then
  181. begin
  182. try
  183. Readln(InputFile, NumOfCols);
  184. except
  185. IsCorrect := False;
  186. end;
  187. if (NumOfCols < 1) or (NumOfCols > 9) then
  188. IsCorrect := False;
  189. end;
  190.  
  191. if (IsCorrect) then
  192. begin
  193. SetLength(Matrix, NumOfRows, NumOfCols);
  194. for I := 0 to High(Matrix) do
  195. for J := 0 to High(Matrix[0]) do
  196. begin
  197. try
  198. Read(InputFile, Matrix[I][J]);
  199. except
  200. IsCorrect := False;
  201. end;
  202. end;
  203. end;
  204. Close(InputFile);
  205. if (IsCorrect) then
  206. GetMatrixFromFile := Matrix;
  207. end;
  208.  
  209. procedure TMainForm.NumOfRowsEditKeyPress(Sender: TObject; var Key: Char);
  210. begin
  211. if not (Key in ['1'..'9', #08]) then
  212. Key := #0;
  213. end;
  214.  
  215. function GetFileState(s : string) : TFileState;
  216. var
  217. sr : TSearchRec;
  218. err : integer;
  219. begin
  220. err := FindFirst(s, faAnyFile and not faDirectory, sr);
  221. if err <> 0
  222. then Result := fsMissing
  223. else if sr.Size = 0
  224. then Result := fsEmpty
  225. else Result := fsSomething;
  226. FindClose(sr);
  227. end;
  228.  
  229. function IsFileCorrect(Path: String): Boolean;
  230. var
  231. FileToCheck: TextFile;
  232. Num: Integer;
  233. IsCorrect: Boolean;
  234. begin
  235. AssignFile(FileToCheck, Path);
  236. Reset(FileToCheck);
  237. IsCorrect := true;
  238. try
  239. Read(FileToCheck, Num);
  240. except
  241. IsCorrect := false;
  242. end;
  243. CloseFile(FileToCheck);
  244. IsFileCorrect := IsCorrect;
  245. end;
  246.  
  247. procedure TMainForm.OpenFromFileMenuClick(Sender: TObject);
  248. var
  249. Matrix: TMatrix;
  250. IsCorrect: Boolean;
  251. NumOfCols, NumOfRows, I, J: Byte;
  252. begin
  253. if OpenFromFile.Execute() then
  254. if IsFileCorrect(OpenFromFile.FileName) then
  255. begin
  256. if (GetFileState(OpenFromFile.FileName) = fsEmpty) then
  257. Application.MessageBox('Файл пустой.', 'Ошибка!', MB_ICONERROR)
  258. else
  259. begin
  260. Matrix := GetMatrixFromFile(OpenFromFile.FileName, IsCorrect);
  261. if IsCorrect then
  262. begin
  263. NumOfRows := Length(Matrix);
  264. NumOfCols := Length(Matrix[0]);
  265. NumOfColsEdit.Text := IntToStr(NumOfCols);
  266. NumOfRowsEdit.Text := IntToStr(NumOfRows);
  267.  
  268. for I := 0 to High(Matrix) do
  269. for J := 0 to High(Matrix[0]) do
  270. sgMatrix.Cells[J+1, I+1] := IntToStr(Matrix[I][J]);
  271. end
  272. else
  273. Application.MessageBox('Данные в файле некорректны.', 'Ошибка!', MB_ICONERROR);
  274. end;
  275. end
  276. else
  277. Application.MessageBox('Данные в файле некорректны.', 'Ошибка!', MB_ICONERROR);
  278. end;
  279.  
  280. procedure FindIncidentList(var IncidentList: TVector; IncidentMatrix: TMatrix);
  281. var
  282. TempList: TVectorCopy;
  283. I, J: Byte;
  284. begin
  285. SetLength(TempList, length(IncidentMatrix));
  286. for I := 0 to High(TempList) do
  287. TempList[I] := TMyArray.Create();
  288. IncidentList := TVector.Create(length(IncidentMatrix));
  289.  
  290. for I := 0 to High(IncidentMatrix) do
  291. begin
  292. for J := 0 to High(IncidentMatrix[0]) do
  293. if(IncidentMatrix[i][j] = 1) or (IncidentMatrix[i][j] = -1) or (IncidentMatrix[i][j] = 2) then
  294. TempList[i].Push_back(j + 1);
  295.  
  296. IncidentList[i] := TempList[i];
  297. end;
  298.  
  299. end;
  300.  
  301. procedure TMainForm.PrintIncidentList(IncidentList: TVector);
  302. var
  303. I, J: Integer;
  304. TempString: String;
  305. begin
  306. IncidentListMemo.Clear();
  307. TempString := '';
  308.  
  309. for I := 0 to IncidentList.Size() - 1 do
  310. begin
  311. TempString := TempString + IntToStr(i+1) + ':';
  312. for J := 0 to IncidentList[i].Size() - 1 do
  313. TempString := TempString + '->' + 'r' + IntToStr(IncidentList[i][j]);
  314. IncidentListMemo.Lines.Add(TempString);
  315. TempString := '';
  316. end;
  317.  
  318. end;
  319.  
  320. function TMainForm.CheckMatrixValues(): Boolean;
  321. var
  322. IsCorrect: Boolean;
  323. I, J: Byte;
  324. Temp: Integer;
  325. begin
  326. IsCorrect := True;
  327.  
  328. with sgMatrix do
  329. begin
  330. for I := FixedRows to RowCount-1 do
  331. for J := FixedCols to ColCount-1 do
  332. begin
  333. try
  334. Temp := StrToInt(Cells[j, i]);
  335. except
  336. IsCorrect := False;
  337. end;
  338. if (Temp < -1) or (Temp > 2) then
  339. IsCorrect := False;
  340. end;
  341. end;
  342.  
  343. CheckMatrixValues := IsCorrect;
  344. end;
  345.  
  346. procedure TMainForm.AboutClick(Sender: TObject);
  347. const
  348. MESSAGE_ONE = 'Данная программа работает с любым типом графа.' + #13#10;
  349. MESSAGE_TWO = 'Следовательно, разрешается вводить -1, 0, 1 и 2 в матрице инциденций.' + #13#10;
  350. MESSAGE_THREE = 'Матрицу можно считать из файла, а список инциденций можно сохранить в файл.' + #13#10;
  351. begin
  352. Application.MessageBox(MESSAGE_ONE+MESSAGE_TWO+MESSAGE_THREE, 'Справка', MB_ICONINFORMATION);
  353. end;
  354.  
  355. function TMainForm.CheckLoopEdges(): Boolean;
  356. var
  357. I, J, K: Byte;
  358. IsCorrect: Boolean;
  359. begin
  360. IsCorrect := True;
  361. I := 1;
  362. J := 1;
  363.  
  364. while((J < sgMatrix.ColCount) and (IsCorrect)) do
  365. begin
  366. while((I < sgMatrix.RowCount) and (IsCorrect)) do
  367. begin
  368. if (sgMatrix.Cells[j,i] = '2') then
  369. begin
  370. K := I + 1;
  371. while(K < sgMatrix.RowCount) do
  372. begin
  373. if (sgMatrix.Cells[j,k] <> '0') then
  374. IsCorrect := False;
  375. Inc(K);
  376. end;
  377. end;
  378.  
  379. inc(I);
  380. end;
  381. if (IsCorrect) then
  382. begin
  383. inc(J);
  384. i := 0;
  385. end;
  386. end;
  387.  
  388. CheckLoopEdges := IsCorrect;
  389. end;
  390.  
  391. function TMainForm.CheckOrientedEdges(): Boolean;
  392. var
  393. IsCorrect: Boolean;
  394. I, J, K, Counter: Byte;
  395. begin
  396. IsCorrect := True;
  397. I := 1;
  398. J := 1;
  399. Counter := 0;
  400.  
  401. while((J < sgMatrix.ColCount) and (IsCorrect)) do
  402. begin
  403. while(I < sgMatrix.RowCount) do
  404. begin
  405. if (sgMatrix.Cells[j,i] = '-1') then
  406. begin
  407. K := 1;
  408. while((K < sgMatrix.RowCount) and (IsCorrect)) do
  409. begin
  410. if (sgMatrix.Cells[j,k] = '1') then
  411. Inc(Counter);
  412.  
  413. if ((K > I) and (sgMatrix.Cells[j,k] = '-1')) then
  414. IsCorrect := False;
  415.  
  416. inc(K);
  417. end;
  418. if(Counter <> 1) then
  419. IsCorrect := False;
  420.  
  421. end;
  422. Counter := 0;
  423. inc(I);
  424. end;
  425. if(IsCorrect) then
  426. begin
  427. inc(J);
  428. i := 0;
  429. end;
  430. end;
  431.  
  432. CheckOrientedEdges := IsCorrect;
  433. end;
  434.  
  435. function TMainForm.CheckNumberOfLinkedNodes(): Boolean;
  436. var
  437. IsCorrect: Boolean;
  438. I, J, Temp: Byte;
  439. begin
  440. IsCorrect := True;
  441. I := 1;
  442. J := 1;
  443. Temp := 0;
  444.  
  445. while((J < sgMatrix.ColCount) and (IsCorrect)) do
  446. begin
  447. while(I < sgMatrix.RowCount) do
  448. begin
  449. if (sgMatrix.Cells[j,i] = '1') then
  450. Inc(Temp);
  451.  
  452. if ((Temp = 2) and (sgMatrix.Cells[j,i] = '2')) then
  453. IsCorrect := False;
  454.  
  455. inc(I);
  456. end;
  457. if (Temp > 2) then
  458. IsCorrect := False
  459. else
  460. begin
  461. inc(J);
  462. i := 0;
  463. Temp := 0;
  464. end;
  465. end;
  466.  
  467. CheckNumberOfLinkedNodes := IsCorrect;
  468. end;
  469.  
  470. procedure TMainForm.ProcesClick(Sender: TObject);
  471. var
  472. Matrix: TMatrix;
  473. NumOfCols, NumOfRows, I, J: Byte;
  474. IncidentList: TVector;
  475. begin
  476. if ((CheckMatrixValues()) and (CheckNumberOfLinkedNodes()) and (CheckOrientedEdges()) and (CheckLoopEdges())) then
  477. begin
  478. NumOfCols := sgMatrix.ColCount - 1;
  479. NumOfRows := sgMatrix.RowCount - 1;
  480. SetLength(Matrix, NumOfRows, NumOfCols);
  481.  
  482. for I := sgMatrix.FixedRows to sgMatrix.RowCount-1 do
  483. for J := sgMatrix.FixedCols to sgMatrix.ColCount-1 do
  484. begin
  485. Matrix[i-1, j-1] := StrToInt(sgMatrix.Cells[j,i]);
  486. end;
  487.  
  488. Application.MessageBox('Данные введены успешно!', 'Информация', MB_ICONINFORMATION);
  489.  
  490. FindIncidentList(IncidentList, Matrix);
  491.  
  492. PrintIncidentList(IncidentList);
  493. end
  494. else
  495. Application.MessageBox('Данные введены некорректно! (См. Справку)', 'Ошибка!', MB_ICONERROR);
  496. end;
  497.  
  498. procedure TMainForm.SaveToFileMenuClick(Sender: TObject);
  499. var
  500. I, J: Byte;
  501. OutputFile: TextFile;
  502. begin
  503. if SaveToFile.Execute() then
  504. begin
  505. AssignFile(OutputFile, SaveToFile.FileName);
  506. Rewrite(OutputFile);
  507. Writeln(OutputFile, 'Входные данные:');
  508. Writeln(OutputFile, 'Количество вершин: ', NumOfRowsEdit.Text);
  509. Writeln(OutputFile, 'Количество рёбер: ', NumOfColsEdit.Text);
  510. Writeln(OutputFile, 'Матрица: ');
  511. with sgMatrix do
  512. begin
  513. for I := FixedRows to RowCount - 1 do
  514. begin
  515. for J := FixedCols to ColCount - 1 do
  516. Write(OutputFile, Cells[J, I], ' ');
  517. Writeln(OutputFile);
  518. end;
  519. end;
  520. Writeln(OutputFile, 'Список инциденций: ');
  521. Writeln(OutputFile, IncidentListMemo.Lines.Text);
  522. CloseFile(OutputFile);
  523. Application.MessageBox('Список инциденций успешно сохранен по указанному пути.', 'Сохранение', MB_ICONINFORMATION);
  524. end;
  525. end;
  526.  
  527. procedure TMainForm.sgMatrixKeyPress(Sender: TObject; var Key: Char);
  528. begin
  529. if (Key <> '0') and (Key <> '1') and (Key <> '2') and (Key <> '-') and (Key <> #8) then
  530. Key := #0;
  531. end;
  532.  
  533. end.
Advertisement
Add Comment
Please, Sign In to add comment