CF
Oct. 17, 2020, 11:35 p.m.

Маленький вопрос для знатоков list

Всем привет, сегодня возникло недоумение, связанное с контейнером list. Может кто объяснить, почему одномерный list можно таким образом использовать как двумерный, и почему это вообще работает?

list mylist [10];

mylist[1].push_back(13); // почему это вообще работает?
mylist[1].push_back(15);

for (int i = 0; i <10; i++)
{
cout « i;
for (auto x : mylist[i]) { cout « " —> " « x; }
cout « endl;
}

Скрин с результатом. Я не понимаю, почему в list работает индексация, если пишут, что она не работает. И почему мы можем сделать список списков из одномерного списка.

5

Do you like it? Share on social networks!

6
Дмитрий
  • Oct. 18, 2020, 4:29 p.m.
  • (edited)

Имелось ввиду это?

  1. std::list<int> mylist[10]

Вы создаете 10 пустых листов и по [1] обращаетесь к массиву из листов (тут может быть имассив int и любой другой массив), а не к элементу листа.
А тут:

  1. for (auto x : mylist[i]) { cout « " —> " « x; }

вы уже обращаетесь непосредственно к элементам листа.

    ИП
    • Oct. 19, 2020, 11:49 a.m.

    В данном примере строчка
    list mylist [10]; (правильнее будет std::list mylist [10])
    создает клсассический массив на 10 элементов, елементами являются std::list
    В результате получаем 10 листов
    Строчки mylist[1].push_back(13); mylist[1].push_back(15); добавляют к одному листу (с инксом 1) сначала значение 13, а потом 15. Соответствующие значения предсказуемо выводятся экран.

    Не совсем понятен вопрос "почему одномерный list можно таким образом использовать как двумерный, и почему это вообще работает?", а какое поведение врообще ожидалось?
    Или напишите какое поведение Вам нужно, а я приведу пример кода с пояснениями "как оно работает..."

      ДК
      • Oct. 19, 2020, 1:44 p.m.

      Почему вы считаете, что односвязный список не может быть х-мерным?
      Я когда-то давно писал свой List:

      1. template<class T>
      2. class List
      3. {
      4. public:
      5. List() :
      6. _head(nullptr), _size(0) {}
      7. ~List () { clear(); }
      8.  
      9. void clear();
      10. void push_back(const T&);
      11. void push_front(const T&);
      12. void pop_front();
      13. void pop_back();
      14. void show();
      15. void remove_at(const size_t);
      16. void insert(const T&, const size_t);
      17. size_t size() { return this->_size; }
      18.  
      19. T& operator[](const size_t);
      20.  
      21. private:
      22.  
      23. template<class T2>
      24. class Node
      25. {
      26. public:
      27. Node* _pnext;
      28. T2 _data;
      29.  
      30. Node(T2 data = T(), Node* pnext = nullptr) :
      31. _data(data), _pnext(pnext) {}
      32. };
      33.  
      34. Node<T>* _head;
      35. size_t _size;
      36. };
      37.  
      38. template<class T>
      39. T& List<T>::operator[](const size_t index)
      40. {
      41. if(index >= 0 && index < _size)
      42. {
      43. size_t counter = 0;
      44. Node<T>*current = _head;
      45.  
      46. while(current != nullptr)
      47. {
      48. if(counter == index)
      49. return current->_data;
      50. current = current->_pnext;
      51. ++counter;
      52. }
      53. }
      54. }
      55.  
      56. template<class T>
      57. void List<T>::push_front(const T& el)
      58. {
      59. _head = new Node<T>(el, _head);
      60. ++_size;
      61. }
      62.  
      63. template<class T>
      64. void List<T>::insert(const T& el, const size_t index)
      65. {
      66. if(index > 0 && index < _size)
      67. {
      68. Node<T>* current = _head;
      69. for(size_t i = 0; i < index - 1; ++i)
      70. current = current->_pnext;
      71. current->_pnext = new Node<T>(el, current->_pnext);
      72. ++_size;
      73. }
      74. else if(index == 0) {
      75. push_front(el);
      76. }
      77. }
      78.  
      79. template<class T>
      80. void List<T>::clear()
      81. {
      82. while(_size)
      83. pop_front();
      84. }
      85.  
      86. template<class T>
      87. void List<T>::pop_back()
      88. {
      89. remove_at(_size - 1);
      90. }
      91.  
      92. template<class T>
      93. void List<T>::remove_at(const size_t _index)
      94. {
      95. if(_index > 0 && _index < _size)
      96. {
      97. Node<T>* previous = _head;
      98. for(size_t i = 0; i < _index - 1; ++i)
      99. previous = previous->_pnext;
      100. Node<T>* toDelete = previous->_pnext;
      101. previous->_pnext = toDelete->_pnext;
      102. delete toDelete;
      103. --_size;
      104. }
      105. else if(_index == 0)
      106. pop_front();
      107. }
      108.  
      109. template<class T>
      110. void List<T>::show()
      111. {
      112. if(_size > 0)
      113. {
      114. size_t counter = 0;
      115. Node<T>* current = _head;
      116. do
      117. {
      118. std::cout << current->_data << " ";
      119. current = current->_pnext;
      120. ++counter;
      121. } while(current != nullptr);
      122. }
      123. }
      124.  
      125. template<class T>
      126. void List<T>::pop_front()
      127. {
      128. if(_size > 0)
      129. {
      130. Node<T>* temp;
      131. temp = _head;
      132. _head = _head->_pnext;
      133. delete temp;
      134. --_size;
      135. }
      136. }
      137.  
      138. template<class T>
      139. void List<T>::push_back(const T& el)
      140. {
      141. if(_head != nullptr)
      142. {
      143. Node<T>* current = this->_head;
      144. while(current->_pnext != nullptr)
      145. current = current->_pnext;
      146. current->_pnext = new Node<T>(el);
      147. }
      148. else {
      149. _head = new Node<T>(el);
      150. }
      151. ++_size;
      152. }

      В Qt push_back просто вызывает append, там такой код:

      1. inline void QList<T>::append(const QList<T> &t)
      2. {
      3. *this += t;
      4. }
        ИП
        • Oct. 19, 2020, 2:15 p.m.
        • (edited)

        Ни кто не запрещает сделать 2-х мерный или даже трехмерный лист, например так

        1. #include <iostream>
        2. #include <list>
        3. int main()
        4. {
        5. std::list<std::list<int>> lmatrix = {{2, 5 , 4, 77, 88}, {1, 11}, {4, 8, 9}, {2, 45, 65, 89}};
        6. std::list<int> &r = lmatrix.front();
        7. r.push_back(100);
        8. for (const std::list<int> & row : lmatrix)
        9. {
        10. for (const int & i : row)
        11. {
        12. std::cout << i << " ";
        13. }
        14. std::cout << std::endl;
        15. }
        16. return 0;
        17. }
          CF
          • Oct. 20, 2020, 12:48 a.m.

          Спасибо, я уже понял, в чем было дело) меня запутали квадратные скобки и название простого массива "mylist". Я думал, что [10] это размер листа, а размер листа задается в круглых скобках. Да и в принципе не часто увидишь, что-бы создавали классический массив хранящий листы, еще и с названием mylist вместо arr.

            ДК
            • Oct. 20, 2020, 1:13 p.m.
            • (edited)

            к элементам списка нельзя через кв скобки обращаться, тк его элементы в памяти не расположены последовательно. Для этого существует метод at(index). Для вектора и обычного массива обращение через кв скобки безопасно.

              Comments

              Only authorized users can post comments.
              Please, Log in or Sign up
              • Last comments
              • AK
                April 1, 2025, 11:41 a.m.
                Добрый день. В данный момент работаю над проектом, где необходимо выводить звук из программы в определенное аудиоустройство (колонки, наушники, виртуальный кабель и т.д). Пишу на Qt5.12.12 поско…
              • Evgenii Legotckoi
                March 9, 2025, 9:02 p.m.
                К сожалению, я этого подсказать не могу, поскольку у меня нет необходимости в обходе блокировок и т.д. Поэтому я и не задавался решением этой проблемы. Ну выглядит так, что вам действитель…
              • VP
                March 9, 2025, 4:14 p.m.
                Здравствуйте! Я устанавливал Qt6 из исходников а также Qt Creator по отдельности. Все компоненты, связанные с разработкой для Android, установлены. Кроме одного... Когда пытаюсь скомпилиров…
              • ИМ
                Nov. 22, 2024, 9:51 p.m.
                Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
              • Evgenii Legotckoi
                Oct. 31, 2024, 11:37 p.m.
                Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup