depth first search c++ - c++

Hello i am working on this project on depth first search, the program uses a linkedlist for each adjacent vertex and use a stack. The program has two structures a Vertex Struct that has two fields a linkedlist pointer and a boolean variable called visted marked as false. The second struct is a Graph that has two fields an array of Vertex Struct and an integer for the number of vertices. The problem i have if when the depth first search function is called it never stops even if the stack is empty the depth first function prints each vertices that is visited. Can someone help me with finding a way to make the program stop ones the stack is empty;
#include <iostream>
#include "linklist.h"
#include "Stack.h"
using namespace std;
typedef int vertexNum;
Stack S;
struct Vertex
{
List p;
bool visted;
Vertex()
{
p = NULL;
visted = false;
}
};
struct Graph
{
int numVert;
Vertex* vertArr;
Graph(int num)
{
numVert = num;
vertArr = new Vertex[numVert+1];
}
};
void readGraph(Graph& G)
{
cout << "Enter adjacent vertices, enter 0 to stop" << endl;
vertexNum v1, v2;
cin >> v1;
while (v1 != 0)
{
cin >> v2;
insertTail(v2,G.vertArr[v1].p);
insertTail(v1,G.vertArr[v2].p);
//G.vertArr[v1].p = cons(v2,G.vertArr[v1].p);
//G.vertArr[v2].p = cons(v1,G.vertArr[v2].p);
cin >> v1;
}
}
void printGraph(Graph& G)
{
for (int i = 1; i <= G.numVert; i++)
{
cout << "Vertex "<< i << " Adjacent list ";
printList(G.vertArr[i].p);
}
}
void DFS(int x,Graph& G)
{
push(x,S);
printList(S.p);
G.vertArr[x].visted = true;
if (!G.vertArr[head(G.vertArr[x].p)].visted)
{
DFS(head(G.vertArr[x].p),G);
}
else
{
cout << ""<< endl;
List temp = tail(G.vertArr[x].p);
if(isEmpty(temp))
{
pop(S);
G.vertArr[peek(S)].visted = false;
DFS(pop(S),G);
}
else if(!G.vertArr[head(temp)].visted)
{
DFS(head(temp),G);
}
else
{
int num =0;
for (List pp = temp; !isEmpty(pp); pp = tail(pp))
{
if(!G.vertArr[head(pp)].visted)
{
num = head(pp);
break;
}
}
if (num == 0)
{
pop(S);
G.vertArr[peek(S)].visted = false;
DFS(pop(S),G);
}
else
DFS(num,G);
}
}
}
int main()
{
int x,y;
cout << "Enter the number of vertices" << endl;
cin >> x;
Graph p(x);
readGraph(p);
printGraph(p);
cout << "\nEnter start vertex" << endl;
cin >> y;
DFS(y,p);
}
The program outputs
Enter the number of vertices
13
Enter adjacent vertices, enter 0 to stop
1 4
1 5
1 2
1 3
2 7
2 8
8 13
8 7
11 12
10 9
13 12
9 6
6 5
0
Vertex 1 Adjacent list 4 5 2 3
Vertex 2 Adjacent list 1 7 8
Vertex 3 Adjacent list 1
Vertex 4 Adjacent list 1
Vertex 5 Adjacent list 1 6
Vertex 6 Adjacent list 9 5
Vertex 7 Adjacent list 2 8
Vertex 8 Adjacent list 2 13 7
Vertex 9 Adjacent list 10 6
Vertex 10 Adjacent list 9
Vertex 11 Adjacent list 12
Vertex 12 Adjacent list 11 13
Vertex 13 Adjacent list 8 12
Enter start vertex
5
5
1 5
4 1 5
1 5
2 1 5
7 2 1 5
8 7 2 1 5
13 8 7 2 1 5
12 13 8 7 2 1 5
11 12 13 8 7 2 1 5
12 13 8 7 2 1 5
13 8 7 2 1 5
8 7 2 1 5
7 2 1 5
2 1 5
1 5
3 1 5
1 5
5
6 5
9 6 5
10 9 6 5
9 6 5
6 5
5
Here is the stack and linkedlist h files
#ifndef LINKLIST_H_
#define LINKLIST_H_
#include <cstdlib>
#include <iostream>
using namespace std;
struct listCell
{
int head;
listCell* tail;
listCell(int h, listCell* t)
{
head =h;
tail = t;
}
};
typedef listCell* List;
typedef const listCell* constList;
List emptyList = NULL;
int head(List L)
{
return L->head;
}
List tail(List L)
{
return L->tail;
}
bool isEmpty(List L)
{
return L == emptyList;
}
List cons(int h, List t)
{
return new listCell(h,t);
}
int listLength(List L)
{
if (isEmpty(L))
{
return 0;
}
else
{
return 1 + listLength(tail(L));
}
}
void printList(List L)
{
List k = L;
while (!isEmpty(k))
{
int val = head(k);
k = k->tail;
cout << val << " ";
}
cout << "\n";
}
here is the stack file
#ifndef STACK_H_
#define STACK_H_
#include "linklist.h"
struct Stack
{
List p;
Stack()
{
p = NULL;
}
};
void push(int x, Stack& list)
{
list.p =cons(x,list.p);
}
int peek(Stack& list)
{
return head(list.p);
}
int pop(Stack& list)
{
return delHead(list.p);
}
bool isEmpty(Stack& list)
{
return isEmpty(list.p);
}
int size(Stack& list)
{
return listLength(list.p);
}
#endif /* STACK_H_ */

Related

taking input until end of file in c++

I am solving a graph problem where I have to take input from a file. Below is my input.txt file.
12
1 2
2 3
2 4
2 5
3 6
4 5
4 7
5 2
5 6
5 7
6 3
6 8
7 8
7 10
8 7
9 7
10 9
10 11
11 12
12 10
In the above input.txt file first input is no of vertices and the others till the end of the file are directed edge of Graph. The first one is the source and the second one is the destination. All the input will be read from the input.txt file.
#include <bits/stdc++.h>
#include <fstream>
using namespace std;
class Graph {
private:
int V;
list<int> *l;
public:
Graph(int V) {
this->V = V;
l = new list<int>[V];
}
void addEdge(int source, int destination) {
// As it is a directed graph edge will be source to destination only
l[source].push_back(destination);
}
void printAdjList() {
for(int i = 1; i <= V; i++) {
cout << "Vertex " << i << "-> " ;
for(int previous: l[i]) {
cout << previous << " " ;
}
cout << endl;
}
}
};
int main() {
// freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
ifstream inputFile;
inputFile.open("input.txt");
int noOfVertex, s, d, noOfEdge=20;
inputFile >> noOfVertex ;
// cout << noOfVertex << endl;
Graph g(noOfEdge);
// while(cin.eof()) {
// // cout << s << " " << d << endl;
// cin >> s >> d;
// g.addEdge(s, d);
// }
if(inputFile) {
while(inputFile >> s >> d) {
// cout << s << " " << d << endl;
g.addEdge(s, d);
}
inputFile.close();
}
else {
cout << "Error opening input file" << endl;
}
g.printAdjList();
return 0;
}
I am getting this result after running the code
Vertex 1-> 2
Vertex 2-> 3 4 5
Vertex 3-> 6
Vertex 4-> 5 7
Vertex 5-> 2 6 7
Vertex 6-> 3 8
Vertex 7-> 8 10
Vertex 8-> 7
Vertex 9-> 7
Vertex 10-> 9 11
Vertex 11-> 12
Vertex 12-> 10
Vertex 13->
Vertex 14->
Vertex 15->
Vertex 16->
Vertex 17->
Vertex 18->
Vertex 19->
I can not take the number of edge for this problem. The number of vetices and given directed edges will be taken one by one line from the file and it will show an adjacency list like that
Vertex 1-> 2
Vertex 2-> 3 4 5
Vertex 3-> 6
Vertex 4-> 5 7
Vertex 5-> 2 6 7
Vertex 6-> 3 8
Vertex 7-> 8 10
Vertex 8-> 7
Vertex 9-> 7
Vertex 10-> 9 11
Vertex 11-> 12
Vertex 12-> 10
How can I take input from the file so that I can get the above output? I have applied many methods but nothing is working.
Your code is wrong for 2 reasons:
you use a hardcoded number of edges when should use the number of vertex
you use an array with an index starting at 0 when the number of the vertex is read from file and does not start at 0
If you want to be safe, you should use a map (or unordered map) int -> list:
...
class Graph {
private:
int V;
unordered_map<int, list<int> > l; // change here
public:
Graph(int V) {
this->V = V;
l.reserve(V); // here
}
...
int noOfVertex, s, d, noOfEdge = 20;
inputFile >> noOfVertex;
// cout << noOfVertex << endl;
Graph g(noOfVertex); // and here
...
That is enough to get as expected:
Vertex 1-> 2
Vertex 2-> 3 4 5
Vertex 3-> 6
Vertex 4-> 5 7
Vertex 5-> 2 6 7
Vertex 6-> 3 8
Vertex 7-> 8 10
Vertex 8-> 7
Vertex 9-> 7
Vertex 10-> 9 11
Vertex 11-> 12
Vertex 12-> 10
I suggest you make your addEdge method more flexible and easier to use. As one problem, if the source input is larger than the size of list your program will crash. The logic should be:
if there is no source vertex, add it
if there is no destination vertex, add it
add link from source to destination.
Here is a more detailed description of the suggested procedure.
/// find vertex "n", returning vertex index, or -1 if missing
int find( int n )
{
loop over graph
if vertex is "n
return index
return -1
}
/// find vertex "n", or add it if not present
int findoradd( int n )
{
int i = find( n );
if( i >= 0 )
return i
return addvertex( n )
}
/// add link between vertices
void addLink( int u, int v )
{
addEdge(
findoradd( u ),
findoradd( v ) );
}

Changing position of data in Input file to a .cpp program Changes output unexpectedly

This is what the code is for:
https://www.codechef.com/LRNDSA04/problems/STACKS
Here is the code snippet:
#include<bits/stdc++.h>
using namespace std;
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int t; cin >> t;
while (t--)
{
int n; cin >> n;
vector<int> a;
while(n--) {
int x; cin >> x;
if(a.empty()) {
a.push_back(x);
} else {
vector<int>::iterator it = upper_bound(a.begin(), a.end(), x);
int pos = it - a.begin();
if(pos == a.size()) {
if(a[pos] > x) {
a[pos] = x;
} else {
a.push_back(x);
}
} else {
a[pos] = x;
}
}
}
cout << a.size();
for(auto e: a) {
cout << " " << e;
}
cout << "\n";
}
return 0;
}
Input to this program is:
2
6
3 4 5 1 1 2
8
14 5 13 19 17 10 18 12
The Unexpected output it generates:
3 1 1 2
3 5 10 12
If the input is changed to:
2
8
14 5 13 19 17 10 18 12
6
3 4 5 1 1 2
It shows up correct output:
4 5 10 12 18
3 1 1 2
The test case with 8 numbers as input if its position is altered in the input file. Then this behavior is observed.
When looking at the run of the code via gdb, it gives expected output for both input files, no problem then.
The output is not justified, what am I missing to see?
In this check:
if(pos == a.size()) {
if(a[pos] > x) { // this is UB
if the condition is true, then you are indexing into an invalid position of a, which invokes undefined behavior.
It seems you want to do
if(pos != a.size()) {
instead. The conventional way to check for this condition is
if(it != a.end()) {

Weird Input output in cpp

I was solving subarray with given sum,Where we have to print the starting and ending index of array if subarray with sum is found , when I tried with two test cases simultaneously i got wrong result
But when I was tried one at a time I got right answer in both.
You please also check in your IDE this is happening in every IDE.
Testcase (Simultaneously)
2
5 12
1 2 3 7 5
10 15
1 2 3 4 5 6 7 8 9 10
Output
2 4 (expected 2 4)
2 5 (But expected 1 5)
But when I tried like this for second test cases
1
10 15
1 2 3 4 5 6 7 8 9 10
Output : 1 5(As expected)
I got correct answer ,why my program this kind of weird behaviour ?
#include<iostream>
#include<vector>
#include<queue>
#include<unordered_map>
using namespace std;
vector<int>a;
unordered_map<int, int>seen;
int main()
{
int t;
cin >> t;
while (t--) {
int n, s;
cin >> n >> s;
a.resize(n);
int sum = 0;
seen[0] = -1;
for (int i = 0; i < n; i++) {
cin >> a[i];
sum += a[i];
if (seen.find(sum - s) != seen.end()) {
int x;
x = seen[sum - s] + 2;
cout << x << " " << i + 1 << endl;
break;
}
else {
seen[sum] = i;
}
}
seen.clear();
a.clear();
//cout<<endl;
}
return 0;
}

Calculate the maximum number of consecutive elements without repetitions in a vector. c++

Hi guys i've to calculate the longest sequence of numbers without any repetitions and return the size of the sub-segment.
The point is that im missing something at some point but I don't know where.
int resolverCaso() {
int num;
int cont = 0;
cin >> num;
int var;
TreeMap<int,int> a;
int aux;
int max = 0;
for (int i = 0; i < num; i++) {
cin >> var;
if (!a.contains(var)) {
a[var] = i;
aux = var;
cont++;
}
else {
if (a[aux]==i-1 && var==aux) {
cont = 1;
a = TreeMap<int, int>();
a[var] = i;
}
else {
a.erase(var);
a[var] = i;
}
}
if (cont > max) {
max = cont;
}
}
return max;
}
I've tried the following cases with this outputs and everything seems to be ok.
E:1 2 3 1 2 3 O:3
E:2 2 2 2 O:1
E:4 5 6 7 6 O:4
E:7 8 9 10 7 8 9 11 2 O:6
E:7 8 9 10 10 10 1 2 3 4 O:5
E:3 4 2 3 4 2 8 9 10 11 O:7
E:0 O:0 ( empty vector ).
E:1 O:1
So basically im looking for some sequence that doesn't work with my code.
Thanks.
The problem is with
else {
a.erase(var);
a[var] = i;
}
You need to do more here. Try the sequence 1 3 4 2 3 4 2 8 9 10 11.

Nested for loops recursion

I looked up in many places and tried to understand how to get arbitrary number of nested for loops via recursion. But what I have understood is clearly wrong.
I need to generate coordinates in an n-dimensional space, in a grid-pattern. The actual problem has different coordinates with different ranges, but to get simpler things right first, I have used the same, integer-stepped coordinate ranges in the code below.
#include <iostream>
using namespace std;
void recursion(int n);
int main(){
recursion(3);
return 0;
}
void recursion(int n)
{
if(n!=0){
for(int x=1; x<4; x++){
cout<<x<<" ";
recursion(n-1);
}
}
else cout<<endl;
}
I want, and was expecting the output to be:
1 1 1
1 1 2
1 1 3
1 2 1
1 2 2
1 2 3
1 3 1
1 3 2
1 3 3
2 1 1
2 1 2
2 1 3
2 2 1
2 2 2
2 2 3
2 3 1
2 3 2
2 3 3
3 1 1
3 1 2
3 1 3
3 2 1
3 2 2
3 2 3
3 3 1
3 3 2
3 3 3
Instead, the output I'm getting is
1 1 1
2
3
2 1
2
3
3 1
2
3
2 1 1
2
3
2 1
2
3
3 1
2
3
3 1 1
2
3
2 1
2
3
3 1
2
3
I just can't figure out whats wrong. Any help to figure out the mistake or even another way to generate coordinates will be greatly appreciated. Thanks!
Non-recursive solution based on add-with-carry:
#include <iostream>
using namespace std;
bool addOne(int* indices, int n, int ceiling) {
for (int i = 0; i < n; ++i) {
if (++indices[i] <= ceiling) {
return true;
}
indices[i] = 1;
}
return false;
}
void printIndices(int* indices, int n) {
for (int i = n-1; i >= 0; --i) {
cout << indices[i] << ' ';
}
cout << '\n';
}
int main() {
int indices[3];
for (int i=0; i < 3; ++i) {
indices[i] = 1;
}
do {
printIndices(indices, 3);
} while (addOne(indices, 3, 3));
return 0;
}
Recursive solution, salvaged from your original code:
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
void recursion(int n, const string& prefix);
int main(){
recursion(3, "");
return 0;
}
void recursion(int n, const string& prefix)
{
if (n!=0) {
for(int x=1; x<4; x++){
ostringstream os;
os << prefix << x << ' ';
recursion(n-1, os.str());
}
}
else cout << prefix << endl;
}
Per Igor's comment, you need an increment function.
Let's use an std::vector to represent each dimension. That is vector[0] is the first dimension, vector[1] is the second dimension and so on.
Using a vector allows us to determine the number of dimensions without any hard coded numbers. The vector.size() will be the number of dimensions.
Here is a function to get you started:
void Increment_Coordinate(std::vector<int>& coordinates,
int max_digit_value,
int min_digit_value)
{
unsigned int digit_index = 0;
bool apply_carry = false;
do
{
apply_carry = false;
coordinates[digit_index]++; // Increment the value in a dimension.
if (coordinates[digit_index] > max_digit_value)
{
// Reset the present dimension value
coordinates[digit_index] = min_digit_value;
// Apply carry to next column by moving to the next dimension.
++digit_index;
apply_carry = true;
}
} while (apply_carry);
return;
}
Edit 1
This is only a foundation. The function needs to be boundary checked.
This function does not support dimensions of varying sizes. That is left as an exercise for reader or OP.