Advertisement
nblknn

Предметный указатель

Mar 30th, 2024 (edited)
350
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 16.28 KB | None | 0 0
  1. ////////////////////////////////////////////////
  2. //   Algorithms and Data Structures; lab #2   //
  3. //           made by nblknn, 351005           //
  4. ////////////////////////////////////////////////
  5. Program Lab2;
  6.  
  7. {$APPTYPE CONSOLE}
  8. {$R *.res}
  9.  
  10. Uses
  11.     System.SysUtils;
  12.  
  13. Type
  14.     PPage = ^TPage;
  15.  
  16.     TPage = Record
  17.         Number: Integer;
  18.         Next: PPage;
  19.     End;
  20.  
  21.     PTerm = ^TTerm;
  22.  
  23.     TTerm = Record
  24.         ParentTerm, Subterm: PTerm;
  25.         Name: String;
  26.         Page: PPage;
  27.         Next: PTerm;
  28.     End;
  29.  
  30. Var
  31.     TermHead: PTerm = Nil;
  32.  
  33. Procedure InsertTerm(Var Term, TermHead: PTerm);
  34. Var
  35.     Temp1, Temp2: PTerm;
  36. Begin
  37.     If TermHead = Nil Then
  38.     Begin
  39.         TermHead := Term;
  40.         Term.Next := Nil;
  41.     End
  42.     Else
  43.     Begin
  44.         Temp1 := TermHead;
  45.         If (Term.Name > Temp1.Name) Then
  46.         Begin
  47.             While (Temp1.Next <> Nil) And (Temp1.Next.Name < Term.Name) Do
  48.                 Temp1 := Temp1.Next;
  49.             Temp2 := Temp1.Next;
  50.             Term.Next := Temp2;
  51.             Temp1.Next := Term;
  52.         End
  53.         Else
  54.         Begin
  55.             Temp2 := TermHead;
  56.             Term.Next := Temp2;
  57.             TermHead := Term;
  58.         End;
  59.     End;
  60. End;
  61.  
  62. Function CreateTerm(Name: String; ParentTerm: PTerm): PTerm;
  63. Var
  64.     NewTerm, Temp: PTerm;
  65. Begin
  66.     NewTerm := New(PTerm);
  67.     NewTerm.Name := Name;
  68.     NewTerm.ParentTerm := ParentTerm;
  69.     NewTerm.Page := Nil;
  70.     NewTerm.Subterm := Nil;
  71.     If ParentTerm = Nil Then
  72.         InsertTerm(NewTerm, TermHead)
  73.     Else
  74.         InsertTerm(NewTerm, ParentTerm.Subterm);
  75.     Result := NewTerm;
  76. End;
  77.  
  78. Procedure InsertPage(NewPage: PPage; Term: PTerm);
  79. Var
  80.     Temp, Temp2: PPage;
  81. Begin
  82.     Temp := Term.Page;
  83.     If (NewPage.Number > Temp.Number) Then
  84.     Begin
  85.         While (Temp.Next <> Nil) And (Temp.Next.Number < NewPage.Number) Do
  86.             Temp := Temp.Next;
  87.         Temp2 := Temp.Next;
  88.         NewPage.Next := Temp2;
  89.         Temp.Next := NewPage;
  90.     End
  91.     Else
  92.     Begin
  93.         Temp2 := Term.Page;
  94.         NewPage.Next := Temp2;
  95.         Term.Page := NewPage;
  96.     End;
  97. End;
  98.  
  99. Procedure CreatePage(Number: Integer; Term: PTerm);
  100. Var
  101.     NewPage: PPage;
  102. Begin
  103.     NewPage := New(PPage);
  104.     NewPage.Number := Number;
  105.     NewPage.Next := Nil;
  106.     If Term.Page = Nil Then
  107.         Term.Page := NewPage
  108.     Else
  109.         InsertPage(NewPage, Term);
  110. End;
  111.  
  112. Procedure EnterTerm(IsSubterm: Boolean; InsertLevel: Integer;
  113.   ParentTerm: PTerm);
  114. Var
  115.     Name, PageStr: String;
  116.     Number, TermHash: Integer;
  117.     Term: PTerm;
  118. Begin
  119.     If Not IsSubterm Then
  120.     Begin
  121.         Write(#13#10'Введите название термина: ');
  122.     End
  123.     Else
  124.         Write(#13#10'Введите название подтермина для "', ParentTerm.Name,
  125.           '", или нажмите Enter для окончания ввода: ');
  126.     Readln(Name);
  127.     While Name <> '' Do
  128.     Begin
  129.         Term := CreateTerm(Name, ParentTerm);
  130.         Repeat
  131.             Write('Введите страницу, или нажмите Enter для окончания ввода: ');
  132.             Readln(PageStr);
  133.             If PageStr <> '' Then
  134.             Begin
  135.                 Number := StrToInt(PageStr);
  136.                 CreatePage(Number, Term);
  137.             End;
  138.         Until PageStr = '';
  139.         { If InsertLevel < 3 Then
  140.           EnterTerm(True, InsertLevel + 1, Term);
  141.           If Not IsSubterm Then
  142.           Exit
  143.           // Write('Введите название термина, или нажмите Enter для окончания ввода: ')
  144.           Else
  145.           Write(#13#10'Введите название подтермина для "', ParentTerm.Name,
  146.           '", или нажмите Enter для окончания ввода: ');
  147.           Readln(Name); }
  148.         Exit;
  149.     End;
  150. End;
  151.  
  152. Procedure ShowList(Term: PTerm; InsertLevel: Integer; Offset: String);
  153. Var
  154.     TempPage: PPage;
  155.     TempTerm: PTerm;
  156. Begin
  157.     TempTerm := Term;
  158.     If (InsertLevel = 4) Or (Term = Nil) Then
  159.         Exit
  160.     Else
  161.         While TempTerm <> Nil Do
  162.         Begin
  163.             Write(Offset, TempTerm.Name);
  164.             TempPage := TempTerm.Page;
  165.             While TempPage <> Nil Do
  166.             Begin
  167.                 Write(', ', TempPage.Number);
  168.                 TempPage := TempPage.Next;
  169.             End;
  170.             Writeln;
  171.             If TempTerm.Subterm <> Nil Then
  172.                 ShowList(TempTerm.Subterm, InsertLevel + 1, Offset + '   ');
  173.             TempTerm := TempTerm.Next;
  174.         End;
  175. End;
  176.  
  177. Procedure ShowTerm(Term: PTerm; InsertLevel: Integer; Offset: String);
  178. Var
  179.     TempPage: PPage;
  180.     TempTerm: PTerm;
  181. Begin
  182.     TempTerm := Term;
  183.     If (InsertLevel = 4) Or (Term = Nil) Then
  184.         Exit
  185.     Else
  186.         While TempTerm <> Nil Do
  187.         Begin
  188.             Write(Offset, TempTerm.Name);
  189.             TempPage := TempTerm.Page;
  190.             While TempPage <> Nil Do
  191.             Begin
  192.                 Write(', ', TempPage.Number);
  193.                 TempPage := TempPage.Next;
  194.             End;
  195.             Writeln;
  196.             If TempTerm.Subterm <> Nil Then
  197.                 ShowList(TempTerm.Subterm, InsertLevel + 1, Offset + '   ');
  198.             TempTerm := TempTerm.Next;
  199.             If InsertLevel = 1 Then
  200.                 Exit;
  201.         End;
  202. End;
  203.  
  204. Function GetTerm(Parent: PTerm): PTerm;
  205. Var
  206.     Name: String;
  207.     Temp: PTerm;
  208.     IsFound: Boolean;
  209. Begin
  210.     Write('Введите требующийся (под)термин: ');
  211.     Readln(Name);
  212.     IsFound := False;
  213.     If Parent = Nil Then
  214.         Temp := TermHead
  215.     Else
  216.         Temp := Parent.Subterm;
  217.     While Not IsFound And (Temp <> Nil) Do
  218.     Begin
  219.         If (Name = Temp.Name) Then
  220.             IsFound := True
  221.         Else
  222.             Temp := Temp.Next;
  223.     End;
  224.     If IsFound Then
  225.         Result := Temp
  226.     Else
  227.     Begin
  228.         Writeln('Такого (под)термина не было найдено...');
  229.         Result := Nil;
  230.     End;
  231. End;
  232.  
  233. Procedure DeletePage(Page: PPage; Var Term: PTerm);
  234. Var
  235.     Temp, Temp2: PPage;
  236. Begin
  237.     Temp := Term.Page;
  238.     If Temp.Number = Page.Number Then
  239.         Temp := Nil
  240.     Else If Temp.Next <> Nil Then
  241.     Begin
  242.         While (Temp.Next <> Nil) And (Temp.Next.Number <> Page.Number) Do
  243.             Temp := Temp.Next;
  244.         If Temp.Next = Nil Then
  245.         Begin
  246.             Temp := Nil;
  247.         End
  248.         Else
  249.         Begin
  250.             Temp.Next := Temp.Next.Next;
  251.         End;
  252.     End
  253.     Else
  254.     Begin
  255.         Term.Page := Nil;
  256.     End;
  257.     Dispose(Page);
  258. End;
  259.  
  260. Procedure DeleteTerm(Term: PTerm);
  261. Var
  262.     Temp, Temp2: PTerm;
  263. Begin
  264.     If Term.ParentTerm <> Nil Then
  265.         Temp := Term.ParentTerm.Subterm
  266.     Else
  267.         Temp := TermHead;
  268.     If Temp.Name = Term.Name Then
  269.     Begin
  270.         If Temp.Next <> Nil Then
  271.         Begin
  272.             If Term.ParentTerm <> Nil Then
  273.                 Term.ParentTerm.Subterm := Term.ParentTerm.Subterm.Next
  274.             Else
  275.                 TermHead := TermHead.Next;
  276.         End;
  277.         Temp := Nil;
  278.     End
  279.     Else If Temp.Next <> Nil Then
  280.     Begin
  281.         While (Temp.Next <> Nil) And (Temp.Next.Name <> Term.Name) Do
  282.             Temp := Temp.Next;
  283.         If Temp.Next = Nil Then
  284.         Begin
  285.             Temp := Nil;
  286.         End
  287.         Else
  288.         Begin
  289.             Temp.Next := Temp.Next.Next;
  290.         End;
  291.     End
  292.     Else
  293.     Begin
  294.         Temp := Nil;
  295.     End;
  296.     Dispose(Term);
  297. End;
  298.  
  299. Function ChangeName(Term: PTerm): PTerm;
  300. Var
  301.     Name: String;
  302.     Temp: PTerm;
  303. Begin
  304.     Write('Введите новое название: ');
  305.     Readln(Name);
  306.     Temp := CreateTerm(Name, Term.ParentTerm);
  307.     Temp.Page := Term.Page;
  308.     Temp.Subterm := Term.Subterm;
  309.     DeleteTerm(Term);
  310.     Result := Temp;
  311. End;
  312.  
  313. Function GetPage(Term: PTerm): PPage;
  314. Var
  315.     Number: Integer;
  316.     Temp: PPage;
  317.     IsFound: Boolean;
  318. Begin
  319.     Write('Введите требующуюся страницу: ');
  320.     Readln(Number);
  321.     IsFound := False;
  322.     Temp := Term.Page;
  323.     While Not IsFound And (Temp <> Nil) Do
  324.     Begin
  325.         If (Number = Temp.Number) Then
  326.             IsFound := True
  327.         Else
  328.             Temp := Temp.Next;
  329.     End;
  330.     If IsFound Then
  331.         Result := Temp
  332.     Else
  333.     Begin
  334.         Writeln('Такой страницы не было найдено...');
  335.         Result := Nil;
  336.     End;
  337. End;
  338.  
  339. Procedure ChangePages(Term: PTerm);
  340. Var
  341.     Choice, PageNumber: Integer;
  342.     EditPage: PPage;
  343. Begin
  344.     // ShowTerm(Term, 1, '');
  345.     While True Do
  346.     Begin
  347.         Write(#13#10'Опции:'#13#10'1. Добавить страницу'#13#10'2. Изменить значение страницы'
  348.           + #13#10'3. Удалить страницу'#13#10'4. Выход' +
  349.           #13#10'Введите номер пункта, который нужно выполнить: ');
  350.         Readln(Choice);
  351.         If Choice In [2, 3] Then
  352.         Begin
  353.             EditPage := GetPage(Term);
  354.             If EditPage = Nil Then
  355.                 Continue;
  356.         End;
  357.         Case Choice Of
  358.             1:
  359.                 Begin
  360.                     Write('Введите значение страницы: ');
  361.                     Readln(PageNumber);
  362.                     CreatePage(PageNumber, Term);
  363.                 End;
  364.             2:
  365.                 Begin
  366.                     Write('Введите новое значение страницы: ');
  367.                     Readln(PageNumber);
  368.                     CreatePage(PageNumber, Term);
  369.                     DeletePage(EditPage, Term);
  370.                 End;
  371.             3:
  372.                 Begin
  373.                     DeletePage(EditPage, Term);
  374.                 End;
  375.             4:
  376.                 Exit;
  377.         End;
  378.     End;
  379. End;
  380.  
  381. Procedure ChangeSubterm(Subterm: PTerm; InsertLevel: Integer);
  382. Var
  383.     Choice: Integer;
  384.     EditSubterm: PTerm;
  385. Begin
  386.     While True Do
  387.     Begin
  388.         Writeln;
  389.         ShowTerm(SubTerm, 2, '');
  390.         Write(#13#10'Опции:'#13#10'1. Изменить название подтермина'#13#10'2. Изменить страницы'
  391.           + #13#10'3. Изменить подтермины'#13#10'4. Удалить подтермин'#13#10'5. Добавить подтермин'#13#10'6. Выход'
  392.           + #13#10'Введите номер пункта, который нужно выполнить: ');
  393.         Readln(Choice);
  394.         Case Choice Of
  395.             1:
  396.                 Subterm := ChangeName(Subterm);
  397.             2:
  398.                 ChangePages(Subterm);
  399.             3:
  400.                 Begin
  401.                     If InsertLevel = 2 Then
  402.                     Begin
  403.                         EditSubterm := GetTerm(Nil);
  404.                         If EditSubterm <> Nil Then
  405.                             ChangeSubterm(EditSubterm, 3);
  406.                     End
  407.                     Else
  408.                         Writeln('Достигнута максимальная вложенность!');
  409.                 End;
  410.             4:
  411.                 Begin
  412.                     DeleteTerm(Subterm);
  413.                     Exit;
  414.                 End;
  415.             5:
  416.                 If InsertLevel = 2 Then
  417.                     EnterTerm(True, InsertLevel + 1, SubTerm)
  418.                 Else
  419.                     Writeln('Достигнута максимальная вложенность!');
  420.             6:
  421.                 Exit;
  422.         End;
  423.     End;
  424. End;
  425.  
  426. Procedure ChangeTerm(Term: PTerm);
  427. Var
  428.     Choice: Integer;
  429.     EditSubterm: PTerm;
  430. Begin
  431.     While True Do
  432.     Begin
  433.         Writeln;
  434.         ShowTerm(Term, 1, '');
  435.         Write(#13#10'Опции:'#13#10'1. Изменить название термина'#13#10'2. Изменить страницы'
  436.           + #13#10'3. Изменить подтермин'#13#10'4. Удалить термин'#13#10'5. Добавить подтермин'#13#10'6. Выход'
  437.           + #13#10'Введите номер пункта, который нужно выполнить: ');
  438.         Readln(Choice);
  439.         Case Choice Of
  440.             1:
  441.                 Begin
  442.                     Term := ChangeName(Term);
  443.                 End;
  444.             2:
  445.                 ChangePages(Term);
  446.             3:
  447.                 Begin
  448.                     EditSubterm := GetTerm(Term);
  449.                     If EditSubterm <> Nil Then
  450.                         ChangeSubterm(EditSubterm, 2);
  451.                 End;
  452.             4:
  453.                 Begin
  454.                     DeleteTerm(Term);
  455.                     Exit;
  456.                 End;
  457.             5:
  458.                 EnterTerm(True, 2, Term);
  459.             6:
  460.                 Exit;
  461.         End;
  462.     End;
  463. End;
  464.  
  465. Procedure FindTerms(TermName: String);
  466. Var
  467.     FindArr: Array Of PTerm;
  468.     Temp: PTerm;
  469. Begin
  470.     Temp := TermHead;
  471.     While Temp <> Nil Do
  472.     Begin
  473.         If Temp.Name = TermName Then
  474.         Begin
  475.             SetLength(FindArr, Length(FindArr) + 1);
  476.             FindArr[High(FindArr)] := Temp;
  477.         End;
  478.         Temp := Temp.Next;
  479.     End;
  480.     Writeln(#13#10'Найденные термины (с подтерминами):');
  481.     For Var I := 0 To High(FindArr) Do
  482.         ShowTerm(FindArr[I], 1, '');
  483. End;
  484.  
  485. Procedure SearchBySubterm(Name: String);
  486. Var
  487.     Temp, Temp2: PTerm;
  488.     FindArr: Array Of PTerm;
  489. Begin
  490.     Temp := TermHead;
  491.     While Temp <> Nil Do
  492.     Begin
  493.         If (Temp.Subterm <> Nil) And (Temp.Subterm.Name = Name) Then
  494.         Begin
  495.             SetLength(FindArr, Length(FindArr) + 1);
  496.             FindArr[High(FindArr)] := Temp;
  497.         End;
  498.         Temp2 := Temp.Subterm;
  499.         While Temp2 <> Nil Do
  500.         Begin
  501.             If (Temp2.Subterm <> Nil) And (Temp2.Subterm.Name = Name) Then
  502.             Begin
  503.                 SetLength(FindArr, Length(FindArr) + 1);
  504.                 FindArr[High(FindArr)] := Temp2;
  505.             End;
  506.             Temp2 := Temp2.Next;
  507.         End;
  508.         Temp := Temp.Next;
  509.     End;
  510.     Writeln(#13#10'Найденные термины:');
  511.     For Var I := 0 To High(FindArr) Do
  512.         Writeln(FindArr[I].Name);
  513. End;
  514.  
  515. Procedure Search();
  516. Var
  517.     Choice: Integer;
  518.     SearchTerm: PTerm;
  519.     Name: String;
  520. Begin
  521.     Write(#13#10'Поиск:'#13#10'1. По термину'#13#10'2. По подтермину'#13#10'3. Выход'
  522.       + #13#10'Введите номер пункта, который нужно выполнить: ');
  523.     Readln(Choice);
  524.     Case Choice Of
  525.         1:
  526.             Begin
  527.                 SearchTerm := GetTerm(Nil);
  528.                 If SearchTerm <> Nil Then
  529.                     FindTerms(SearchTerm.Name);
  530.             End;
  531.         2:
  532.             Begin
  533.                 Write('Введите требующийся подтермин: ');
  534.                 Readln(Name);
  535.                 SearchBySubterm(Name);
  536.             End;
  537.         3:
  538.             Exit;
  539.     End;
  540. End;
  541.  
  542. Var
  543.     Choice: Integer;
  544.     EditTerm: PTerm = Nil;
  545.  
  546. Begin
  547.     Writeln('Добро пожаловать в программу для работы с предметным указателем!');
  548.     While True Do
  549.     Begin
  550.         Write('Меню:'#13#10'1. Добавить термин'#13#10'2. Изменить термин' +
  551.           #13#10'3. Просмотр предметного указателя'#13#10'4. Поиск'#13#10'5. Выход'
  552.           + #13#10'Введите номер пункта, который нужно выполнить: ');
  553.         Readln(Choice);
  554.         Case Choice Of
  555.             1:
  556.                 EnterTerm(False, 1, Nil);
  557.             2:
  558.                 Begin
  559.                     EditTerm := GetTerm(Nil);
  560.                     If EditTerm <> Nil Then
  561.                         ChangeTerm(EditTerm);
  562.                 End;
  563.             3:
  564.                 Begin
  565.                     Writeln(#13#10'ПРЕДМЕТНЫЙ УКАЗАТЕЛЬ:');
  566.                     Try
  567.                         ShowList(TermHead, 1, '');
  568.                     Except
  569.                         Writeln;
  570.                     End;
  571.                 End;
  572.             4:
  573.                 Search;
  574.             5:
  575.                 Break;
  576.         End;
  577.         Writeln('Нажмите Enter для возвращения в меню...');
  578.         Readln;
  579.     End;
  580.  
  581. End.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement