简体   繁体   中英

how do i print a vector of arrays/lists using int iterator in cpp?

I want to declare a 2d array of 500 * 500 size(for example).

Is a vector of arrays the best way to go?

I can't seem to print the array and every other code declares the iterator of vector type but i want to do it using int type.

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<list>
#include<stack>
#define white 0
#define black 1
using namespace std;

void print(vector< list<int> > adjList)
{
    for(int i = 0; i<adjList.size(); i++)
    {
        for(int j = adjList[i].begin(); j != adjList[i].end(); j++)
        {
            cout<<j<<" "; //adjList[i][j] doesnt work

        }
        cout<<endl;
    }
}

int main()
{
        int n,m;
        cin>>n>>m;
        vector< list<int> > adjList;

        for(int i = 0; i<m ; i++)
        {
            int u,v;
            cin>>u>>v;
            adjList[u].push_back(v);
            adjList[v].push_back(u);
        }

        print(adjList);


}

The problem is you have a vector of lists, but list does not define operator[], which you then try to use to access the elements of it.

Since you say you want a fixed array 500 x 500, you don't want a vector of lists anyway, because lists are not a fixed length.

So try a vector of vectors, for example.

You cannot use int to iterate over the list.
List in C++ are implemented using doubly linked list in which they uses pointers to access the next/previous elements.
The type I would recommend you to use is list<int>::iterator as it is a standard way to iterate over a list.
There are some other ways to do it also. For example:

for(auto x : adjList[i]){
    cout << x << " "; // Do something
      // Only valid in C++11 or newer.
}

Another example:

for(auto j = adjList[i].begin(); j != adjList[i].end(); j++){
    cout << *j << " "; // Do something with j (iterator) or *j (value).
      // Only valid in C++11 or newer.
}

For the classic C++ example would be:

for(list<int>::iterator it = adjlist[i].begin(); it != adjlist[i].end(): it++){
    cout << *it << " ";
}

You can't iterate through a list with an integer, but you can declare j as an iterator ( std::list<int>::iterator j = adjList[i].begin(); ) and use the asterisk like in pointers to get the element that an iterator is pointing at like this: cout << *j << ' '; . If you want to print a vector of arrays, just do it like how you would normally print a 2D array. The std::list container implements a linked list and is very different from containers that store elements in contiguous memory such as arrays and std::vector , which is likely not what you want here since it doesn't have random access.

By the way, if you want to pass large containers like vectors to a function like print() that does not need to modify the vector, you should use a constant reference instead of copying the vector. There is something called a range based for loop in C++11 that can iterate through things like vectors without you having to worry about things like iterators, and a std::set is probably more suited for implementing an adjacency list since it allows for checking if two vertices are adjacent with logarithmic complexity.

Lastly, in your input loop, you used adjList[u] when that element does not exist yet since adjList is empty. You should add a line adjList.resize(n) after you input n to create the empty sets or just declare adjList after you input n and use n as the constructor argument like this to tell the constructor to initialize adjList with a bunch of empty sets: vector<set<int>> adjList(n); .

Since it looks like you are doing a competitive programming problem, I would advise you to convert the input to zero indexing before doing any processing.

My code using range based for loops:

#include <iostream>
#include <vector>
#include <set>

void print(const std::vector<std::set<int>> &adjList)//pass by const reference
{
    for(std::size_t i = 0; i < adjList.size(); i++)
    {
        std::cout << i << ": ";
        for(auto &j : adjList[i])//range based for loop to iterate through adjList[i] and use the reference j to refer to each element
        {
            std::cout << j << ' ';
        }
        std::cout << '\n';
    }
}

int main()
{
    int n, m;
    std::cin >> n >> m;
    std::vector<std::set<int>> adjList(n); //adjList starts with n empty sets
    for(int i = 0; i < m; i++)
    {
        int u, v;
        std::cin >> u >> v;
        adjList[u].insert(v);
        adjList[v].insert(u);
    }
    print(adjList);
}

you can use range based for loop in your print function like below:

void print(vector< list<int> > adjList)
{   
    for(auto i : adjList)
    {
        for(auto j: i)
        {
           cout << j << " ";
        }
    }
}

however you will get seg fault when you run your code. The main function below should be self explanatory

int main()
{
    int n,m;
    cin>>n>>m;
    vector< list<int> > adjList;

    cout << "entered value : n" << n <<" m : "<<m <<endl;
    for(int i = 0; i<m ; i++)
    {
        int u,v;
        cin>>u>>v;
        adjList.push_back({v});
        adjList.push_back({u});
    }
    print(adjList);
}

Note that a std::list is not an array and does not support indexing with operator[] . You could simply replace the use of list throughout your program with vector instead, and print() would look something like

void print(vector< vector<int> > adjList)
{
    for (int i = 0; i < adjList.size(); i++)
    {
        for (int j = 0; j < adjList[i].size(); j++)
        {
            cout << adjList[i][j] << ' ';
        }
        cout << endl;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM