Как напечатать vector <vector <int>> в с ++? [дубликат]

1

Я пытаюсь назначить и распечататьvector<vector<int>> динамически, однако я не могу понять, как это сделать, я застрял здесь, это моя программа

#include<iostream>
#include<vector>
#include<string>
using namespace std;
class A {
public:
    vector<int> getVector(int s) {

        vector <int> A(s);
        for (int j = 0; j < s; j++) {
            A.push_back(j);
        }
        return A;
    }
};
int main() {
    A obj;
    int n = 5;
    vector<vector<int>> A;
    
    A.push_back(obj.getVector(n));     // pushes a vector on vector A
    A.push_back(obj.getVector(n - 1));

    vector<vector<int>> ::iterator it;
    it = A.begin();
    for (it; it != A.end(); it++) {
        cout << *it;
    }


    return 0;
}
  • 2
    Для этого вам понадобится две петли. std::vector<int> не имеет определенного оператора вывода для std::ostream . Так что просто вложите еще один цикл for в тот, который у вас уже есть.
  • 0
    не могли бы вы опубликовать фрагмент кода, я очень новичок в C ++ и STL, пожалуйста
  • 0
    Я считаю, что это достаточно просто, и у вас будет лучший эффект обучения, если вы разберетесь в этом сами. Код, который у вас есть, почти готов. Так что нет.
  • 0
    Избегайте использования одного и того же имени для класса и переменной.
  • 0
    измените vector <int> A(s) на vector <int> A иначе, скажем, для n = 5 он создаст вектор длины 5, инициализированный с помощью {0, 0, 0, 0, 0} и снова нажмите {0, 1, 2, 3, 4} и, наконец, приведет к {0, 0, 0, 0, 0, 0, 1, 2, 3, 4}
  • 0
    Вы пытаетесь напечатать вектор напрямую, так как *it в основном вектор, поскольку it является итератором вектора. Это простой подход: сохраните этот вектор в vector<int> например vector<int> v = *it а затем распечатайте v с помощью цикла.
Теги:
c++11 vector
CodeFix

5 ответов

1
Лучший ответ
vector<vector<int>> ::iterator it;
    it = A.begin();
    for (it; it != A.end(); it++) {
        for(vector<int>::iterator it2 = it->begin(); it2 != it->end(); ++it2)
            cout << *it2;
    }
Поделиться
Источник
  • 1
    Отлично, это то, что я искал! Теперь я понимаю это, в основном, мы должны инициализировать несколько итераторов в зависимости от того, сколько вложений у нас есть, спасибо :)
2

Рассматривайте vector <vector> как динамический 2D-массив.

Для этого вам потребуется 2 петли.

Также вам нужно изменить несколько вещей:

  1. vector <int> A(s); инициализирует вектор размераs со всеми элементами, установленными на0 а затем вы нажимаете первыйn элементы вA . Итак, изменилосьvector <int> A(s); кvector <int> A; .

  2. using namespace std не считается хорошей практикой. Узнай почему.

Взгляните на следующую реализацию:

#include<iostream>
#include<vector>
#include<string>

class A {
    
    public:
        
        std::vector<int> getVector(int s) {

            std::vector <int> A; //Change 1

            for (int j = 0; j < s; j++) {
                A.push_back(j);
            }
            return A;
        }
};

int main() {

    A obj;
    int n = 5;
    std::vector<std::vector<int>> test_vector;
    
    test_vector.push_back(obj.getVector(n));     // pushes a vector on vector A
    test_vector.push_back(obj.getVector(n - 1));

    std::vector<std::vector<int>> :: iterator test_vector_iterator;
    
    test_vector_iterator = test_vector.begin();
    
    for (test_vector_iterator; test_vector_iterator != test_vector.end(); test_vector_iterator++) {
        
        std::vector<int> :: iterator inner_vector_iterator = (*test_vector_iterator).begin();

        for(inner_vector_iterator; inner_vector_iterator != (*test_vector_iterator).end(); inner_vector_iterator++){

            std::cout << *inner_vector_iterator <<" ";
        }

        std::cout << std::endl;
    }


    return 0;
}

Выход:

0 1 2 3 4 
0 1 2 3 
Поделиться
Источник
  • 0
    Спасибо за подробное рассмотрение дальнейших проблем в моем коде :)
  • 0
    Всегда! Пожалуйста, проголосуйте за ответ, если это помогло.
2

Используйте цикл диапазона, например

for( const auto &i : A )      // for elements in A, i is vector<int>
{
    for( const auto &j : i )  // for sub elements in A, j is int
    {
        std::cout<<j;
    }
}

или используя итератор

for( vector<vector<int>>::iterator i = A.begin() ; i != A.end(); i++ )
{
    for( vector<int>::iterator j = i->begin(); j != i->end(); j++ )
    {
        std::cout<<*j;
    }
}

Спасибо.

Поделиться
Источник
  • 2
    Скорее всего, это больше сбивает с толку ОП, чем помогает. Они уже правильно поняли итераторы, и теперь вы представляете им совершенно новую концепцию без каких-либо дополнительных объяснений.
  • 1
    согласованные итераторы пока хороши, и первый метод немного сбивает с толку, однако он обновил решение, написанное обоими способами, поэтому я думаю, что он заслуживает +1 :)
1

Вложенный std :: for_each может помочь

Applies the given function object f to the result of dereferencing every iterator in the range [first, last), in order.

Мы сделаемf братьstd::vector<int> в качестве аргумента и распечатайте его.

#include <iostream>
#include <vector>
#include <algorithm>


int main()
{
    std::vector<std::vector<int>> A{ {1,2}, {3, 4} };

    std::for_each(A.begin(), A.end(), [](const auto& v) {
        std::for_each(v.begin(), v.end(), [](auto const& it) {
            std::cout << it << std::endl;
        });
    });

    return 0;
}

Выход

1
2
3
4
Поделиться
Источник
0

Вектор векторов является аналогом 2-го массива. Стандартного метода сериализации вектора нет, подойдет вложенный цикл.

#include<iostream>
#include<vector>
#include<string>
#include <algorithm>

using std::for_each;
using std::cout;
using std::vector;
using std::endl;

class A {
public:
    vector<int> getVector(int s) {

        vector <int> A(s);
        for (int j = 0; j < s; j++) {
            A.push_back(j);
        }
        return A;
    }
};
int main() {
    A obj;
    int n = 5;
    vector<vector<int>> A;
    
    A.push_back(obj.getVector(n));     // pushes a vector on vector A
    A.push_back(obj.getVector(n - 1));

    // classic for loop
    for (auto itV = A.begin(), itVE =  A.end(); itV != itVE; itV++)
    {
        for (auto itI = itV->begin(), itIE = itV->end(); itI != itIE; itI++) 
        {
             cout << *itI;
        }
    }
    cout << endl;
    
    // much simpler range-based loop
    for (auto& rowV : A )     // note that this a reference 
                              // - no copy of stored vector is made.
        for (auto el : rowV)
             cout << el;

    cout << endl;

    // a generic lambda to serialize vector
    auto print_vector =  [](const auto& v) {
        std::for_each(v.begin(), v.end(), [](auto const& it) {
            std::cout << it << std::endl;
        });
    };

    std::for_each(A.begin(), A.end(), print_vector );

    return 0;
}

Есть несколько способов сделать это: использовать классический for (), который довольно полон, но позволяет контролировать некоторые аспекты, цикл for на основе диапазона является самым коротким и кратким вариантом. Третий подход - использование идиоматической функции из стандартной библиотеки, напримерfor_each , что потребует создания вызываемого объекта, что может быть предпочтительным, если вызываемый объект может использоваться повторно или быть заменен чем-то другим, что обеспечивает некоторую гибкость.

Поделиться
Источник
  • 0
    Не подходящее использование for_each
  • 0
    @ lajoh90686 прости?
  • 0
    for_each не предназначен для немедленного вызова таким образом. У вас есть циклы for на основе диапазона и даже обычные циклы for для этого. Это слишком сложное неправильное использование или чрезмерно спроектированное решение простого цикла for.
  • 0
    @ lajoh90686 мы понятия не имеем, для чего на самом деле предназначены OP, его пример - это минимальное развлечение. for_each и подобные, предназначенные для идиоматического использования в коде шаблона или универсальном коде, использование в общей лямбда-выражении уместно, потому что это шаблон. То, что OP на самом деле делает и выбирает, зависит от их реального приложения. В C ++ 20 мы также распараллелили аналоги этих итерационных функций, но здесь это не имеет значения. Обратите внимание, что некоторые частично совместимые, но популярные в определенных отраслях компиляторы не поддерживают диапазон, но поддерживают эти другие функции.
  • 0
    // pushes a vector on vector A Ясно, что OP только учится. Вам будет сложно найти такой вопрос, где ответ - std :: for_each. За многие годы программирования на C ++ for_each - одна из самых бесполезных функций библиотеки алгоритмов. Особенно, когда вы можете просто сделать for(auto a: std::ranges::view::reverse(as)) (или заменить reverse любым вашим помощником итератора - я выбрал C ++ 20, потому что он стандартный)
  • 0
    @ lajoh90686 мне непонятно, потому что в реальной жизни мне задают тот же вопрос от программистов с опытом работы 10-20 лет. Такие действия выходили за рамки их компетенции, и они подвергались особым ограничениям. И хотя for_each наиболее бесполезен, ранжированный for - один из наиболее часто запрещенных корпоративным стандартом кодирования, особенно в случае C ++ для чипов и контроллеров. Слишком легко внести огромные затраты на пространство или сложность, создав односимвольный тип, и труднее обнаружить или обнаружить ошибку, потому что базовые действия были в синтаксическом сахаре. Например, в этом случае забудьте &.

Другие вопросы

CodeFix
Цитата дня

"Завидую тестировщикам: все хотят с ними дружить."

Эндрю Таненбаум