CF
Қаз. 17, 2020, 11:35 Т.Қ.

Маленький вопрос для знатоков 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

Ол саған ұнайды ма? Әлеуметтік желілерде бөлісіңіз!

6
Дмитрий
  • Қаз. 18, 2020, 4:29 Т.Қ.
  • (өңделген)

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

std::list<int> mylist[10]

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

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

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

    ИП
    • Қаз. 19, 2020, 11:49 Т.Ж.

    В данном примере строчка
    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 можно таким образом использовать как двумерный, и почему это вообще работает?", а какое поведение врообще ожидалось?
    Или напишите какое поведение Вам нужно, а я приведу пример кода с пояснениями "как оно работает..."

      ДК
      • Қаз. 19, 2020, 1:44 Т.Қ.

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

      template<class T>
      class List
      {
      public:
          List() :
              _head(nullptr), _size(0) {}
          ~List () { clear(); }
      
          void clear();
          void push_back(const T&);
          void push_front(const T&);
          void pop_front();
          void pop_back();
          void show();
          void remove_at(const size_t);
          void insert(const T&, const size_t);
          size_t size() { return this->_size; }
      
          T& operator[](const size_t);
      
      private:
      
          template<class T2>
          class Node
          {
          public:
              Node* _pnext;
              T2 _data;
      
              Node(T2 data = T(), Node* pnext = nullptr) :
                  _data(data), _pnext(pnext) {}
          };
      
          Node<T>* _head;
          size_t _size;
      };
      
      template<class T>
      T& List<T>::operator[](const size_t index)
      {
          if(index >= 0 && index < _size)
          {
              size_t counter = 0;
              Node<T>*current = _head;
      
              while(current != nullptr)
              {
                  if(counter == index)
                      return current->_data;
                  current = current->_pnext;
                  ++counter;
              }
          }
      }
      
      template<class T>
      void List<T>::push_front(const T& el)
      {
          _head = new Node<T>(el, _head);
          ++_size;
      }
      
      template<class T>
      void List<T>::insert(const T& el, const size_t index)
      {
          if(index > 0 && index < _size)
          {
              Node<T>* current = _head;
              for(size_t i = 0; i < index - 1; ++i)
                  current = current->_pnext;
              current->_pnext = new Node<T>(el, current->_pnext);
              ++_size;
          }
          else if(index == 0) {
              push_front(el);
          }
      }
      
      template<class T>
      void List<T>::clear()
      {
          while(_size)
              pop_front();
      }
      
      template<class T>
      void List<T>::pop_back()
      {
          remove_at(_size - 1);
      }
      
      template<class T>
      void List<T>::remove_at(const size_t _index)
      {
          if(_index > 0 && _index < _size)
          {
              Node<T>* previous = _head;
              for(size_t i = 0; i < _index - 1; ++i)
                  previous = previous->_pnext;
              Node<T>* toDelete = previous->_pnext;
              previous->_pnext = toDelete->_pnext;
              delete toDelete;
              --_size;
          }
          else if(_index == 0)
              pop_front();
      }
      
      template<class T>
      void List<T>::show()
      {
          if(_size > 0)
          {
              size_t counter = 0;
              Node<T>* current = _head;
              do
              {
                  std::cout << current->_data << " ";
                  current = current->_pnext;
                  ++counter;
              } while(current != nullptr);
          }   
      }
      
      template<class T>
      void List<T>::pop_front()
      {
          if(_size > 0)
          {
              Node<T>* temp;
              temp = _head;
              _head = _head->_pnext;
              delete temp;
              --_size;
          }
      }
      
      template<class T>
      void List<T>::push_back(const T& el)
      {
          if(_head != nullptr)
          {
              Node<T>* current = this->_head;
              while(current->_pnext != nullptr)
                  current = current->_pnext;
              current->_pnext = new Node<T>(el);
          }
          else {
              _head = new Node<T>(el);
          }
          ++_size;
      }
      

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

      inline void QList<T>::append(const QList<T> &t)
      {
          *this += t;
      }
      
        ИП
        • Қаз. 19, 2020, 2:15 Т.Қ.
        • (өңделген)

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

        #include <iostream>
        #include <list>
        int main()
        {
            std::list<std::list<int>> lmatrix = {{2, 5 , 4, 77, 88}, {1, 11}, {4, 8, 9}, {2, 45, 65, 89}};
            std::list<int> &r = lmatrix.front();
            r.push_back(100);
            for (const std::list<int> & row : lmatrix)
            {
                for (const int & i : row)
                {
                    std::cout << i << " ";
                }
                std::cout << std::endl;
            }
            return 0;
        }
        
          CF
          • Қаз. 20, 2020, 12:48 Т.Ж.

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

            ДК
            • Қаз. 20, 2020, 1:13 Т.Қ.
            • (өңделген)

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

              Пікірлер

              Тек рұқсаты бар пайдаланушылар ғана пікір қалдыра алады.
              Кіріңіз немесе Тіркеліңіз