Стек на основе списка - C#

Узнай цену своей работы

Формулировка задачи:

Всем привет, нужна ваша помощь в решении следующей задачи: Из элементов двух стеков, хранящих слова, собрать новый стек со словами длины K (задается пользователем),

изменив связи

между элементами стеков (не выделяя новую память). В исходных стеках должны остаться неиспользованные слова. Классы, реализующие список, объединены в пространство имен LinkedListLibrary и находятся в отдельном файле класса ListNode.cs
Листинг программы
  1. using System;
  2. namespace LinkedListLibrary
  3. {
  4. class ListNode
  5. {
  6. public object Data { get; private set; }
  7. public ListNode Next { get; set; }
  8. public ListNode(object dataValue)
  9. : this(dataValue, null)
  10. {
  11. }
  12. public ListNode(object dataValue, ListNode nextNode)
  13. {
  14. Data = dataValue;
  15. Next = nextNode;
  16. }
  17. }
  18. public class List
  19. {
  20. private ListNode firstNode;
  21. private ListNode lastNode;
  22. private string name;
  23. public List(string listName)
  24. {
  25. name = listName;
  26. firstNode = lastNode = null;
  27. }
  28. public List()
  29. : this("list")
  30. {
  31. }
  32. //метод: вставка объекта в начале списка List. Если список пуст, то
  33. //firstNode и lastNode содержит ссылку на один и тот же объект.
  34. //Иначе, firstNode содержит ссылку на новый узел.
  35. public void InsertAtFront(object insertItem)
  36. {
  37. if (IsEmpty())
  38. firstNode = lastNode = new ListNode(insertItem);
  39. else
  40. firstNode = new ListNode(insertItem, firstNode);
  41. }
  42. //метод: вставка объекта в конец списка List
  43. public void InsertAtBack(object insertItem)
  44. {
  45. if (IsEmpty())
  46. firstNode = lastNode = new ListNode(insertItem);
  47. else
  48. lastNode = lastNode.Next = new ListNode(insertItem);
  49. }
  50. //метод: удаление первого узла из списка List
  51. public object RemoveFromFront()
  52. {
  53. if (IsEmpty())
  54. throw new EmptyListException(name);
  55. object removeItem = firstNode.Data; //сохранение данных
  56. //изменение ссылок firstNode и lastNode
  57. if (firstNode == lastNode)
  58. firstNode = lastNode = null;
  59. else
  60. firstNode = firstNode.Next;
  61. return removeItem; //возврат удаленных данных
  62. }
  63. //метод: удаление последнего узла из списка List
  64. public object RemoveFromBack()
  65. {
  66. if (IsEmpty())
  67. throw new EmptyListException(name);
  68. object removeItem = firstNode.Data;
  69. if (firstNode == lastNode)
  70. firstNode = lastNode = null;
  71. else
  72. {
  73. ListNode current = firstNode;
  74. //выполнять, пока current.Next отлично от lastNode
  75. while (current.Next != lastNode)
  76. current = current.Next;
  77. //current становится новым значением lastNode
  78. lastNode = current;
  79. current.Next = null;
  80. }
  81. return removeItem;
  82. }
  83. //метод: возврат true, если список List путой
  84. public bool IsEmpty()
  85. {
  86. return firstNode == null;
  87. }
  88. //метод: вывод содержимого списка List
  89. public void Display()
  90. {
  91. if (IsEmpty())
  92. Console.WriteLine("Пустой " + name);
  93. else
  94. {
  95. Console.Write("список {0} содержит: ", name);
  96. ListNode current = firstNode;
  97. while (current != null)
  98. {
  99. Console.Write(current.Data + " ");
  100. current = current.Next;
  101. }
  102. Console.WriteLine("\n");
  103. }
  104. }
  105. }
  106. public class EmptyListException : Exception
  107. {
  108. public EmptyListException()
  109. : base("Список пустой")
  110. {
  111. }
  112. public EmptyListException(string name)
  113. : base("Список " + name + " пустой")
  114. {
  115. }
  116. }
  117. }
Класс StackInheritance для работы со стеком объединен в пространство имен StackInheritanceLibrary и находится в отдельном файле класса StackInheritance.cs. Работа со стеком реализуется наследованием от класса List.
Листинг программы
  1. using System;
  2. using LinkedListLibrary;
  3. namespace StackInheritanceLibrary
  4. {
  5. public class StackInheritance : List
  6. {
  7. public StackInheritance()
  8. : base("stack") { }
  9. public StackInheritance(string n)
  10. : base(n) { }
  11. public void Push(object dataValue)
  12. {
  13. InsertAtFront(dataValue);
  14. }
  15. public object Pop()
  16. {
  17. return RemoveFromFront();
  18. }
  19. }
  20. }
Класс StackInheritanceTest для тестирования работы со стеком.
Листинг программы
  1. using System;
  2. using StackInheritanceLibrary;
  3. using LinkedListLibrary;
  4. class StackInheritanceTest
  5. {
  6. public static void Main()
  7. {
  8. StackInheritance stack = new StackInheritance("stack1");
  9. stack.Push("Рот");
  10. stack.Push("Нет");
  11. stack.Push("Да");
  12. stack.Push("no");
  13. StackInheritance stack2 = new StackInheritance("stack2");
  14. stack2.Push("На");
  15. stack2.Push("но");
  16. StackInheritance stack3 = new StackInheritance("stack3");
  17. Console.WriteLine("Содержимое стеков до: ");
  18. stack.Display();
  19. stack2.Display();
  20. stack3.Display();
  21. Console.Write("Введите число: ");
  22. int k = Convert.ToInt32(Console.ReadLine());
  23. //здесь нужно вызвать метод, который будет решать поставленную задачу
  24. Console.WriteLine("\nСодержимое стеков после: ");
  25. stack.Display();
  26. stack2.Display();
  27. stack3.Display();
  28. }
  29. }
Долго сидел над задачей, в классе List добавил свойство, чтобы получить ссылку на первый элемент стека:
Листинг программы
  1. public ListNode FirstNode
  2. {
  3. get {return firstNode;}
  4. }
но для этого мне пришлось внести изменения в класс ListNode, сделав его открытым (преподаватель сказал, что этим я нарушил принципы ООП, но я не знаю, как иначе получить доступ к firstNode). Затем в классе StackInheritance я создал метод, который проходится по всему стеку и копирует слова длины k в новый стек:
Листинг программы
  1. public void Move(int k, StackInheritance stack)
  2. {
  3. ListNode c = FirstNode;
  4. while (c != null)
  5. {
  6. string temp = (string)c.Data;
  7. if (temp.Length == k)
  8. stack.Push(c.Data);
  9. c = c.Next;
  10. }
  11. }
но я не изменяю связи, как это требуется в задании, поэтому в исходных стеках все остается без изменений, а должны остаться только неиспользованные слова. Я понимаю, что нужно изменить метод таким образом, чтобы firstNode.Next указывал на следующий эл-т стека длины k, но для этого мне нужно хранить все ссылки и потом как-то вывести то, что осталось в исходном стеке. У меня не получается это сделать.

Решение задачи: «Стек на основе списка»

textual
Листинг программы
  1.         public void Delete(int k)
  2.         {
  3.             ListNode prev = null;
  4.             ListNode cur = firstNode;
  5.  
  6.             while (cur != null)
  7.             {
  8.                 // Иначе не узнать длину строки, с другими типами не будет работать
  9.                 string data = (string)cur.Data;
  10.  
  11.                 if (data.Length == k)
  12.                 {
  13.                     if (prev == null) // Удаляем первый элемент
  14.                     {
  15.                         firstNode = cur.Next;
  16.                         cur = firstNode;
  17.                         continue;
  18.                     }
  19.  
  20.                     // Перебрасываем ссылку
  21.                     prev.Next = cur.Next;
  22.                     cur = prev.Next;
  23.                 }
  24.                 else
  25.                 {
  26.                     // Сдвигаемся на следующий элемент
  27.                     prev = cur;
  28.                     cur = cur.Next;
  29.                 }
  30.             }
  31.         }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

8   голосов , оценка 3.625 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы