Struct does not provide a subscript operator - c++

I'm trying to loop through my adjacency list in my DFS search class, but its giving me this error: type 'AdjList' does not provide a subscript operator. I feel like it might be the way i saved adjList constructor for DFS but I'm not sure. I saw other solutions saw it has to be passed as a pointer so I changed AdjList list in the constructor to AdjList* list but that did not work. Here is my code:
main.cpp
AdjList::AdjList(){}
AdjList::AdjList(vector<Node> nodeVector){
nodeContainer = nodeVector;
}
void AdjList::makeAdjList(){
int temp;
for(int i = 0; i < nodeContainer.size(); i++){
connections = nodeContainer[i].getConnectionsVector();
for(int x = 0; x < connections.size(); x++){
innerList.push_back(nodeContainer[connections[x] - 1]);
}
adjList.push_back(innerList);
innerList.clear();
}
}
//other AdjList functions
int main(){
vector<Node> nodeContainer;
nodeContainer = load();
AdjList adjList(nodeContainer);
adjList.makeAdjList();
DFS search(nodeContainer, adjList);
search.iterative(6,3);
}
DFS.cpp
DFS::DFS(vector<Node> nodeVec, AdjList list){
nodeContainer = nodeVec;
adjList = list;
}
vector<Node> DFS::iterative(int src, int dest){
vector<Node> vectorPath;
list<Node>::iterator it;
int i = 6;
for(it = adjList[i].begin(); it != adjList[i].end(); it++){ //this is where the
//error is happening
cout << it->getNodeID() << " ";
}
return vectorPath;
}
AdjList.h
class AdjList{
private:
public:
list<Node> innerList;
vector<list<Node> > adjList;
vector<Node> nodeContainer;
vector<int> connections;
int temp;
AdjList();
AdjList(vector<Node> nodeVector);
void makeAdjList();
void displayAdjList();
};

When you say adjList[i], C++ looks for an operator[] in the type of adjList which is AdjList. As this type doesn't have such a member function you get the error message that it's missing.
Supply a
std::list<Node>& operator[](std::size_t i);
std::list<Node> const& operator[](std::size_t i) const;
and return adjList[i] in both.

Related

Breadth First Search implementing to vector of Linked List

Can anybody explain me, how to do Breadth first search in the graph that uses vector of linked lists ?
My Graph header file:
#include <string>
#include <iostream>
#include <map>
#include <vector>
using namespace std;
struct vertex {
string code;
vertex* next;
};
struct AdjList {
vertex *head;
AdjList(vertex* Given) {
head = Given;
}
};
class Graph {
map<string, string> associations;
int nodeNum; //amount of nodes or size of the graph;
vector<AdjList> adjList;
public:
Graph(int NodeNum);
~Graph();
int singleSize(string codeName);
int getSize();// must destroy every prerequisite list connected to the node
vertex* generateVertex(string codeName);
int getIndexOfVertex(vertex* givenVertex); // will find the location of the vertex in the array
void addVertex(vertex* newVertex);
void addEdge(string codeName, string linkCodeName);
void printPrerequisites(vertex* ptr, int i);
bool deleteVertex(string codeName);
bool deleteEdge(string codeName, string linkCodeName);
bool elemExistsInGraph(string codeName);
void printPrereq(string codeName);
void printCourseTitle(string codeName);
void printGraph();
};
I am trying to print all connected nodes within the graph using the breadth first search. Here is my code for the breadth first search algorithm that does not work.
void Graph::printPrereq(string codeName) {
int adjListSize = this->adjList.size();
int index = getIndexOfVertex(generateVertex(codeName));
bool visited[this->adjList.size()];
for(int i = 0; i < adjListSize; i++) {
visited[i] = false;
}
list<int> queue;
visited[index] = true;
queue.push_back(index);
while(!queue.empty()) {
index = queue.front();
vertex* pointer = this->adjList[index].head;
cout << pointer->code;
queue.pop_front();
while(pointer != nullptr){
if(!visited[getIndexOfVertex(pointer)]) {
queue.push_back(getIndexOfVertex(pointer));
visited[getIndexOfVertex(pointer)] = true;
}
cout << pointer->code <<"->";
pointer = pointer->next;
}
cout << "Null" << endl;
}
}
This algorithm outputs nodes that are only within the linked list, but not the ones that are connected through the graph.
Can anybody help and solve this problem?

How does the code for comparison object actually work?

I was learning the dijkstra's algorithm and then in that there was the concept of priority queue with min_heap implementation where my priority_queue <Node,vector<Node>,comp> min_heap and the comp is a comparison struct;
struct Edge{
int src;
int dest;
int weight;
};
struct Node{
int vertex;
int weight;
};
class Graph{
public:
vector<vector<Edge>> adjList;
Graph(vector<Edge> &edges,int N){
adjList.resize(N);
for(auto &edge:edges){
adjList[edge.src].push_back(edge);
}
}
};
struct comp{
bool operator()(const Node &lhs,const Node &rhs) const{
return lhs.weight>rhs.weight;
}
};
void dij(Graph g,int source,int N){
priority_queue<Node,vector<Node>,comp> min_heap;
min_heap.push({source,0});
vector<int> dist(N,INT_MAX);
dist[source] = 0;
vector<bool> done(N,false);
done[0] = true;
while(!min_heap.empty()){
Node node = min_heap.top();
min_heap.pop();
int u = node.vertex;
for(auto i:g.adjList[u]){
int v = i.dest;
int weight = i.weight;
if(!done[u] && dist[u]+weight<dist[v]){
dist[v] = dist[u] + weight;
min_heap.push({v,dist[v]});
}
}
done[u] = true;
}
cout<<"The path from vertex "<<source<<" to "<<N<<" is "<<dist[N];
}
The code works fine and prints the minimum cost but I am not understanding the struct comp(); and how this works.

Access private struct within class c++

Trying to implement an adjacency matrix graph and practice OOP. I've been stuck on implementing the inserNode(string ) method.
My troubles are with accessing the private data fields. What am I completely missing?
Some of the errors:
Graph.cpp:30:26: error: unknown type name 'node'
graph[id] = new node;
^
Graph.cpp:35:10: error: use of undeclared identifier 'numnodes'
numnodes++;
Graph.cpp:34:19: error: expected ';' at end of declaration
graph[id]->nodename = name;
Graph.cpp:34:15: error: decomposition declaration '[id]' requires an initializer
graph.h
#include <iostream>
using namespace std;
class Graph {
public:
Graph();
int insertNode(string name);
private:
static const int vertices = 20;
int nodeCount;
struct node {
int nodeid; // node position in graph[]
string nodename; // username
};
// pointers to the graph nodes
node *graph[vertices];
// adjacency matrix for graph. True if edge is going from node i to j.
bool edges[vertices][vertices];
};
#endif
graph.cpp
#include "Graph.h"
Graph::Graph() {
for (int i = 0; i < vertices; i++) {
graph[i] = 0;
for (int j = 0; j < vertices; j++ )
edges[i][j] = 0;
}
}
/* create node and insert pointer in first available graph position. Returns id value, -1 if unsuccessful. */
int insertNode(string name) {
int id = 0;
while (id < vertices) {
if (graph[id] == NULL) {
graph[id] = new node;
if (!graph[id])
return -1;
graph[id]->nodeid = id;
graph[id]->nodename = name;
numnodes++;
return id;
}
id++;
}
return -1;
}
The insertNode you've defined is not the same way you declared in Graph. You've just made a free function called insertNode, which isn't a member of Graph and therefore can't access Graph. You need to define it like so:
int Graph::insertNode(string name)
{
}

Typedef array referencing?

Hello I have a question regarding the usage of typedef in C++. I am trying to create my own graph class where I can perform DFS and BFS. I have attached what I have for the class so far. But every time I try to compile I run into certain errors that I just do not know how to fix. I am sure the error has something to do with the variable vertexList that I use to hold all the vertices.
#include <iostream>
#include <stack>
class myGraph{
public:
typedef struct Vertex{
char label;
bool visited;
}Vertex;
myGraph(int);
void AddVertex(char);
void addEdge(int, int);
int adjUnvisited(int);
void displayVertex(int);
void dfs();
private:
Vertex* vertexList;
int** adjMatrix;
int size;
int vertices;
int count;
};
myGraph::myGraph(int size){
count = 0;
size = size;
vertices = size;
vertexList = new Vertex[vertices];
adjMatrix = new int*[size];
for(int i=0; i<size; i++){
adjMatrix[i] = new int[vertices];
}
for(int i=0; i<vertices; i++){
for(int j=0; j<vertices; j++){
adjMatrix[i][j] = 0;
}
}
}
void myGraph::AddVertex(char label){
Vertex* myVertex = new Vertex();
myVertex->label = label;
myVertex->visited = false;
vertexList[count++] = myVertex;
}
void myGraph::addEdge(int a, int b){
adjMatrix[a][b] = 1;
adjMatrix[b][a] = 1;
}
int myGraph::adjUnvisited(int index){
for(int i=0; i<vertices; i++){
if(adjMatrix[i][index]==1 && vertexList[i]->visited==false){
return i;
}
}
return -1;
}
void myGraph::displayVertex(int index){
std::cout << "Current vertex: " << vertexList[index]->label << std::endl;
}
void myGraph::dfs(){
std::stack<int> myStack;
int temp = 0;
vertexList[temp]->visited = true;
myStack.push(temp);
int unvisitedVertex;
while(!myStack.empty()){
unvisitedVertex = adjUnvisited[myStack.top()];
if(unvisitedVertex!=-1){
myStack.push(unvisitedVertex);
displayVertex(unvisitedVertex);
vertexList[unvisitedVertex]->visited = true;
}else{
myStack.pop();
}
}
}
The error message that I get is this:
no viable overloaded '=' vertexList[count++] = myVertex;
Along with a note:
candidate function (the implicit copy assignment
operator) not viable: no known conversion from 'struct Vertex *' to
'const myGraph::Vertex' for 1st argument; dereference the argument with *
struct Vertex{
And some other error messages which are (I'm sure these are very minor and I can figure them out):
member reference type 'struct Vertex' is not a
pointer; maybe you meant to use '.'?
if(adjMatrix[i][index]==1 && vertexList[i]->visited==false){
reference to non-static member function must be called
unvisitedVertex = adjUnvisited[myStack.top()];
Now I am not sure what exactly I am doing wrong and was wondering if someone here could help me out.
Thank you very much for all your help!
You've declared vertexList as a pointer-to-Vertex - which is fair enough, since it's going to be an array. But that means that each element of that array is a Vertex structure - yet you're accessing each array element as though it was a pointer.
Either:
Replace all the ->s with .s and do something different in AddVertex()
Declare vertexList as a Vertex ** (like adjMatrix)

How to get the min value of an object in a list (C++)

I've a question to ask.
So, I have a structure call Node as shown below:
struct Node
{
int xKoor, yKoor;
Node *parent;
char nodeId;
float G;
float H;
float F;
Node(int x, int y, int id, Node * par)
{
xKoor = x;
yKoor = y;
nodeId = id;
parent = 0;
}
Node(int x, int y, char id)
{
xKoor = x;
yKoor = y;
nodeId = id;
}
};
And I have list that contains elements of this structure:
list<Node*> OPEN;
This list's size varies in time.
What I need to do is to find the Node object which has the minimum F value, then pop out that object from the list.
So, I tried to write a function as shown below:
void enKucukFliNodeBul(list<Node*> OPEN)
{
list<Node*>::iterator it = OPEN.begin();
for(it = OPEN.begin(); it != OPEN.end(); it++)
{
if(it._Ptr->_Myval->F < it._Ptr->_Next->_Myval->F)
{
}
}
}
But I'm stuck. I'm new to STL. How can I solve this?
My best regards...
You can use std::min_element with a suitable comparison function for this.
bool nodeComp(const Node* lhs, const Node* rhs) {
return lhs->F < rhs->F;
}
#include <algorithm> // for std::min_element
list<Node*>::iterator it = std::min_element(OPEN.begin(), OPEN.end(), nodeComp);
This assumes that list<Node*> is std::list<Node*>, in which case you should be aware that std::list itself is a linked list.
Other useful operations, based on your comments:
Remove a minimum value node from the list and delete it:
OPEN.erase(it);
delete *it; //
You may need to perform other operations, if your nodes depend on each other.
Sort the list:
OPEN.sort(nodeComp);
use std::min_element algirithm and overload Compare function
bool compareF(Node *lhs, Node *rhs)
{
return lhs->F < rhs->F;
}
if you are using C++03:
std::<Node*>::itertor ter = std::min_element(OPEN.begin(),OPEN.end(), compareF);
if you are using C++11:
auto iter = std::min_element(OPEN.begin(),OPEN.end(), compareF);
To sort the list, you can call OPEN.sort(compareF); to sort your list with compareF function
Try adding this:
bool compare_node_F(Node* n1, Node* n2)
{
return n1-> F< n2-> F;
}
#include <list>
#include <algorithm>
#include <cstdlib>
#include <iostream>
int main()
{
std::list<Node*> nodes;
for(int i= 100; i--;)
{
Node* n= new Node(42, 42, 42);
n-> F= i;
nodes.push_back(n);
}
std::list<Node*>::iterator min_element_iter= std::min_element(nodes.begin(), nodes.end(), compare_node_F);
std::cout<< "Min F: "<< (*min_element_iter)-> F<< '\n';
for(std::list<Node*>::iterator d= nodes.begin(); d!= nodes.end(); ++ d)
delete *d;
}