Values in array are changing when exiting - c++

So I'm trying to implement breadth first search for determining the shortest path in a bipartite graph for a project. The problem I am having is that the values of my initial arrays are changing from the "bfs" function to the "printShortestPath" function as can be seen at the end. What would be causing the array values to randomly change?
Header:
#define BGRAPH_H
using namespace std;
#include <vector>
#include <list>
class bgraph {
public:
bgraph(int numV);
void addEdge(int v1, int v2);
bool bfs(int v1, int v2);
void printShortestPath(int v1, int v2);
void removeDuplicates();
private:
int numVertex;
vector<vector<int>> adjacencyLists;
bool visited[];
int pred[];
int dist[];
};
#endif
Cpp
using namespace std;
#include "bgraph.h"
#include <list>
#include <set>
#include <iostream> // TEST
bgraph::bgraph(int numV) {
numVertex = numV;
adjacencyLists.resize(numV);
bool visited[numV] = {false};
int pred[numV];
int dist[numV];
cout << "got to constructor\n";
for (int i = 0; i < numVertex; i++) {
pred[i] = -1;
dist[i] = 1000;
}
cout << "pred:\n";
for (int i = 0; i < numVertex; i++)
cout << pred[i] << " ";
cout << endl << endl;
cout << "dist:\n";
for (int i = 0; i < numVertex; i++)
cout << dist[i] << " ";
cout << endl << endl;
cout << "visited:\n";
for (int i = 0; i < numVertex; i++)
cout << visited[i] << " ";
cout << endl << endl;
}
void bgraph::addEdge(int v1, int v2) {
adjacencyLists.at(v1).push_back(v2);
adjacencyLists.at(v2).push_back(v1);
}
bool bgraph::bfs(int v1, int v2) {
list<int> queue;
visited[v1] = true;
dist[v1] = 0;
queue.push_back(v1);
// Look at values of pred, dist, and visisted
cout << "pred:\n";
for (int i = 0; i < numVertex; i++)
cout << pred[i] << " ";
cout << endl << endl;
cout << "dist:\n";
for (int i = 0; i < numVertex; i++)
cout << dist[i] << " ";
cout << endl << endl;
cout << "visited:\n";
for (int i = 0; i < numVertex; i++)
cout << visited[i] << " ";
cout << endl << endl;
while (!queue.empty()) {
int currentVertex = queue.front();
queue.pop_front();
for (int i = 0; i < adjacencyLists.at(currentVertex).size(); i++) {
int nextVertex = adjacencyLists.at(currentVertex).at(i);
if (!visited[nextVertex]) {
//cout << "Next vertex: " << nextVertex << endl; // TEST
visited[nextVertex] = true;
dist[nextVertex] = dist[currentVertex] + 1;
//cout << "dist[nextVertex]: " << dist[nextVertex] << endl; // TEST
pred[nextVertex] = currentVertex;
//cout << "pred[nextVertex]: " << pred[nextVertex] << endl; // TEST
queue.push_back(nextVertex);
if (nextVertex == v2) {
return true;
}
}
}
}
return false;
}
void bgraph::printShortestPath(int v1, int v2) {
if (!bfs(v1, v2)) {
cout << "No connection.\n";
return;
}
vector<int> shortestPath;
int iter = v2;
shortestPath.push_back(iter);
while (pred[iter] != -1) {
shortestPath.push_back(pred[iter]);
iter = pred[iter];
}
cout << "Path is: \n";
for (int i = shortestPath.size() - 1; i >= 0; i--)
cout << shortestPath.at(i) << " ";
cout << endl;
}
void bgraph::removeDuplicates() {
set<int> noDuplicates;
for (int i = 0; i < adjacencyLists.size(); i++) {
for (int j = 0; j < adjacencyLists.at(i).size(); j++)
noDuplicates.insert(adjacencyLists.at(i).at(j));
adjacencyLists.at(i).clear();
if (noDuplicates.find(i) != noDuplicates.end())
noDuplicates.erase(i);
set<int>::iterator iter = noDuplicates.begin();
while (iter != noDuplicates.end()) {
adjacencyLists.at(i).push_back(*iter);
iter++;
}
noDuplicates.clear();
}
}
Output in constructor:
pred:
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
dist:
1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000
visited:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Output of same arrays when they're being called in bfs function:
pred:
12124608 0 0 0 12131016 32566 -1417405256 32764 -1417405245 32764 -1417405245 32764 0 0 0 0 0 0 12158624 32566 8 0 -1417405256 32764 11 0 1634493778 824206708 3487008 0 12131304 32566 6 0 0 0 4098 0 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 8 0 -1417405176 32764 12158624 32566 0 0 0 0 -1417405344 32764 12157120 32566 12157008 32566 12157024 32566 0 0 0 1
dist:
12124608 0 0 0 12131016 32566 -1417405256 32764 -1417405245 32764 -1417405245 32764 0 0 0 0 0 0 12158624 32566 8 0 -1417405256 32764 11 0 1634493778 824206708 3487008 0 12131304 32566 6 0 0 0 4098 0 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 8 0 -1417405176 32764 12158624 32566 0 0 0 0 -1417405344 32764 12157120 32566 12157008 32566 12157024 32566 0 0 0 1
visited:
192 1 185 0 0 0 0 0 0 0 0 0 0 0 0 0 200 26 185 0 54 127 0 0 184 28 132 171 252 127 0 0 195 28 132 171 252 127 0 0 195 28 132 171 252 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 160 134 185 0 54 127 0 0 8 0 0 0 0 0 0 0 184 28 132 171 252 127 0 0 11 0 0 0
Any help is really appreciated.

Related

Loading a 2D array from an input file into a Function

I am having trouble loading a 10x10 array from an input file and storing it into an array. I have written this so far:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void LoadImage(const string imagefile, int image[MAXROWS][MAXCOLS]) //Function to load in image
{
ifstream inputs;
int i,j;
inputs.open(imagefile.c_str());
getline(inputs, imagefile[i][j]);
inputs.ignore(10000,'\n');
if (inputs.is_open())
{
for( i=0; i < MAXROWS; i++ )
{
for ( j=0; i < MAXCOLS; j++ )
{
inputs >> image[i][j];
}
}
}
inputs.close();
}
The void LoadImage function and was given to me with those specific parameters to use or the main function will not execute.
An example of an input file:
#Sample Image--1
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 1 1 1 1 0 0 0 0
0 0 1 1 1 1 0 0 0 0
0 0 0 0 0 0 1 1 0 0
0 0 0 0 0 0 1 1 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
Where I have to get rid of the header of the input file before building the array.
If I compile what I have now I get the "error: invalid types ‘const char[int]’ for array subscript
getline(inputs, imagefile[i][j]);"
I understand why I am getting the error, but I do not know how to fix it.
I appreciate any help I can get!
The code is generally OK, just following the comments and fixing a few small mistakes should work.
Note specially the terminating condition for the following loop:
for ( j=0; i < MAXCOLS; j++ )
Should be instead:
for ( j=0; j < MAXCOLS; j++ )
This is the reason why you're getting an infinite loop.
Here's the complete code:
#include <iostream>
#include <fstream>
#include <string>
#define MAXROWS 10
#define MAXCOLS 10
using namespace std;
void LoadImage(const string imagefile, int image[MAXROWS][MAXCOLS]) //Function to load in image
{
ifstream inputs;
int i,j;
inputs.open(imagefile.c_str());
if (inputs.is_open())
{
for( i=0; i < MAXROWS; i++)
{
for ( j=0; j < MAXCOLS; j ++)
{
std::string str;
inputs >> image[i][j];
}
}
}
inputs.close();
}
void PrintImage(int image[MAXROWS][MAXCOLS])
{
int i,j;
for(i = 0; i < MAXROWS; i++)
{
for (j = 0; j < MAXCOLS; j ++)
{
cout << image[i][j] << " ";
}
cout << endl;
}
}
int main()
{
int image[MAXROWS][MAXCOLS] = {0,};
LoadImage ("img.mtx", image);
PrintImage (image);
}
And testing:
$ cat img.mtx
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 1 1 1 1 0 0 0 0
0 0 1 1 1 1 0 0 0 0
0 0 0 0 0 0 1 1 0 0
0 0 0 0 0 0 1 1 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
$ g++ main.cpp && ./a.out
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 1 1 1 1 0 0 0 0
0 0 1 1 1 1 0 0 0 0
0 0 0 0 0 0 1 1 0 0
0 0 0 0 0 0 1 1 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
The line
getline(inputs, imagefile[i][j]);
does not make sense.
If you want to ignore the first line of the input file, then you should simply use inputs.ignore, as you are already doing afterwards. So you can simply delete the line which calls getline.
Another problem is that the line
for ( j=0; i < MAXCOLS; j++ )
should probably be
for ( j=0; j < MAXCOLS; j++ )
i.e. you wrote i instead of j.

Initialize 2d Array at compile and allow user input

I am trying to declare an array that is sized at runtime/compile through an overload constructor.
private:
auto** arr = new int[n][n];
overloadConstruct(int n){
arr[n][n] = {0,0};
}
This does not work, it says the second n needs to be constant and auto is not allowed. Any help would be appreciated. I am not sure of all the rules with arrays, especially 2d arrays when doing this. I just need to be able to size a 2d array at runtime/compile through an input.
Use a vector of vectors instead:
#include <iostream>
#include <vector>
class Foo
{
public:
Foo( const int rowCount, const int colCount )
: m_2dArray( rowCount, std::vector<int>( colCount ) ) // initialize the vector
{ // member like this
}
void printArr() const
{
for ( size_t row = 0; row < m_2dArray.size( ); ++row )
{
for ( size_t col = 0; col < m_2dArray[ 0 ].size( ); ++col )
{
std::cout << m_2dArray[ row ][ col ] << " ";
}
std::cout << '\n';
}
}
private:
std::vector< std::vector<int> > m_2dArray; // the vector member
};
int main ()
{
int rowCount { };
int colCount { };
std::cout << "Enter row count: ";
std::cin >> rowCount;
std::cout << "Enter column count: ";
std::cin >> colCount;
std::cout << "\nThe contents of 2D array:\n";
Foo obj( rowCount, colCount ); // construct the object using user's input
obj.printArr( );
}
The output:
Enter row count: 10
Enter column count: 20
The contents of 2D array:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
As you can see, the user can enter the values at runtime.

Why is this BFS queue size so large?

I am recently working with BFS algorithm. I made a maze solving program with this algorithm. here is my code:
#include<iostream>
#include<cmath>
#include<sstream>
#include<vector>
#include<queue>
#include <unistd.h>
using namespace std;
int m,n;
inline int indexFor(int x,int y) {
return (x-1) + m*(y-1);
}
int main() {
FILE *file = fopen("test_case","r"); // test_case file
//build maze
fscanf(file,"%d",&m);
fscanf(file,"%d",&n);
vector<int> grid((m+1)*(n+1));
for(int i=1;i<=m;i++) {
for(int j =1;j<=n;j++) {
int k;
fscanf(file,"%d",&k);
grid[indexFor(i,j)] = k;
}
}
int startX,startY,endX,endY;
fscanf(file,"%d",&startX);
fscanf(file,"%d",&startY);
fscanf(file,"%d",&endX);
fscanf(file,"%d",&endY);
//bfs starts
queue<int> x,y;
x.push(1);
y.push(1);
vector<int> visited((m+1)*(n+1),0);
vector<vector<int>> path_track((m+1)*(n+1),vector<int>(2,0));
while(x.size()>0) {
int k = x.front(), l = y.front();
x.pop();
y.pop();
visited[indexFor(k,l)]=1;
// this part for printing each steps
cout << "\033[2J\033[H";
cout << "queue size: " << x.size()<<endl;
for(int i=1;i<=m;i++) {
for(int j =1;j<=n;j++) {
if(visited[indexFor(i,j)]==1) cout << "* ";
else {
if(grid[indexFor(i,j)]==0) {
cout << ". ";
} else {
cout << "# ";
}
}
}
cout << endl;
}
usleep(10);
if(k-1>0) {
if(grid[indexFor(k-1,l)] != 1 && visited[indexFor(k-1,l)]!=1) {
x.push(k-1);
y.push(l);
path_track[indexFor(x.back(),y.back())] = {k,l};
}}
if((k+1)<=m) {
if(grid[indexFor(k+1,l)] != 1 && visited[indexFor(k+1,l)]!=1) {
x.push(k+1);
y.push(l);
//cout << "Path_track: "<<x.back() << ", " << y.back() << " : " << k << ", " << l <<endl;
path_track[indexFor(x.back(),y.back())] = {k,l};
}}
if(l-1>0) {
if(grid[indexFor(k,l-1)] != 1 && visited[indexFor(k,l-1)]!=1) {
x.push(k);
y.push(l-1);
path_track[indexFor(x.back(),y.back())] = {k,l};
}}
if(l+1<=n) {
if(grid[indexFor(k,l+1)] != 1 && visited[indexFor(k,l+1)]!=1) {
x.push(k);
y.push(l+1);
path_track[indexFor(x.back(),y.back())] = {k,l};
}}
}
cout << "\033[2J\033[H";
vector<vector<int>> path;
path.push_back({endX,endY});
while(endX!=0&&endY!=0) {
int kx = endX, ky = endY;
endX = path_track[indexFor(kx,ky)][0];
endY = path_track[indexFor(kx,ky)][1];
path.push_back({endX,endY});
}
path.pop_back();
if(path[path.size()-1][0] == startX && path[path.size()-1][1] == startY)
{
for(vector<int> l:path) grid[indexFor(l[0],l[1])] = 8;
for(int i=1;i<=m;i++) {
for(int j =1;j<=n;j++) {
if(grid[indexFor(i,j)]==8) {
cout << "X ";
} else {
if(grid[indexFor(i,j)]==0) {
cout << ". ";
} else {
cout << "# ";
}
}
}
cout << endl;
}
} else {
cout << "No path found\n";
for(vector<int> l:path) grid[indexFor(l[0],l[1])] = 8;
for(int i=1;i<=m;i++) {
for(int j =1;j<=n;j++) {
if(grid[indexFor(i,j)]==8) {
cout << "X ";
} else {
if(grid[indexFor(i,j)]==0) {
cout << ". ";
} else {
cout << "# ";
}
}
}
cout << endl;
}
}
//cout<<path_track[indexFor(2,2)][0]<<","<<path_track[indexFor(2,2)][1]<<endl;
return 0;
}
I made a maze_generator for this problem which is :
#include <iostream>
#include <vector>
using namespace std;
int m,n;
inline int indexFor(int x,int y) {
return m * (x-1) + (y-1);
}
int main() {
srand(time(nullptr));
FILE * f = fopen("test_case","w");
cin >> m;
cin >> n;
vector<int> grid(m*n,0);
fprintf(f,"%d %d\n",m,n);
for(int i = 0; i<grid.size();i++) {
int k = (rand()%7);
if(i == 0 || i==grid.size()-1 ) k = 0;
grid[i] = k<5?0:1;
}
grid[indexFor(m,n)] = 0;
for(int i = 1;i<=m;i++) {
for(int j = 1; j<=n;j++) {
cout << grid[indexFor(i,j)] << " ";
fprintf(f,"%d ",grid[indexFor(i,j)]);
}
cout<<endl;
fprintf(f,"\n");
}
fprintf(f,"1 1\n%d %d",m,n);
return 0;
}
which generated this test_case:
21 50
0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 1 0 1 0 0 0 1 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 0 0 1 1 1 0 0 1 0 1
0 0 0 1 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 0 0 1 1 1 0 0 1 0 1 0 0 0 1 0 0 0 1 0 1 1 0 0 0 1 0 1 0 0 0 0
1 1 1 0 0 1 0 1 0 0 0 1 0 0 0 1 0 1 1 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 1 0 0 0 1 1 0 0 0 0
0 1 0 1 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 1 0 0 0 1 1 0 0 0 0 1 0 1 1 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0
0 0 1 1 0 0 0 0 1 0 1 1 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 0 0 1 1 1 1 0 0 0
0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 0 0 1 1 1 1 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
0 1 1 1 1 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 1 1 1 1 0 0 0 1 0 0 0 0 1 0
0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 1 1 1 1 0 0 0 1 0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0
0 1 0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 0 1 1 0 0 1 0 1 0 0 1 0 0 0 0 0 1 1 0 0
0 0 0 0 1 0 0 0 0 0 1 1 0 0 1 0 1 0 0 1 0 0 0 0 0 1 1 0 0 0 1 0 0 1 1 0 0 0 0 0 0 0 1 1 1 0 1 1 0 1
0 0 0 0 1 1 0 0 0 1 0 0 1 1 0 0 0 0 0 0 0 1 1 1 0 1 1 0 1 0 1 1 0 0 0 0 1 0 1 0 0 0 0 0 1 0 0 0 0 1
1 1 1 0 1 1 0 1 0 1 1 0 0 0 0 1 0 1 0 0 0 0 0 1 0 0 0 0 1 0 1 0 1 0 0 0 0 1 0 0 0 1 0 1 0 1 0 1 0 0
0 0 1 0 0 0 0 1 0 1 0 1 0 0 0 0 1 0 0 0 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0
0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 1 1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 1 0 1
1 0 1 0 0 0 0 0 1 1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 1 1
0 0 0 1 0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 1 1 0 0 0 1 1 0 0 0 1 1 1 1 0 0 1 0 0 0 0 0 0
0 0 1 1 0 0 1 1 0 0 0 1 1 0 0 0 1 1 1 1 0 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 0 1 1 1 0 0 0 0 0
0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 1 0 0 0 0 0 0 1 0 0 1
1 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 1 0 0 0 0 0 0 1 0 0 1 1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 0
0 0 0 0 1 0 0 1 1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 1 0 1 1 1 0 0
1 1
21 50
In the test case the last two line represents starting and ending point for the maze. In case for maze 0 indicates free path and 1 indicates wall. 1st line denotes the size of maze.
Problem is that when I solve it the queue size jumped to 130k+ for this particular test_case. Is there something I missing? or it is normal?
I solved the problem. Looks like i needed use another array for queue mapping to check if a point is already queued. Here is the final solution:
#include<iostream>
#include<cmath>
#include<sstream>
#include<vector>
#include<queue>
#include <unistd.h>
using namespace std;
int m,n;
inline int indexFor(int x,int y) {
return (x-1) + m*(y-1);
}
int main() {
FILE *file = fopen("test_case","r");
fscanf(file,"%d",&m);
fscanf(file,"%d",&n);
vector<int> grid((m+1)*(n+1));
for(int i=1;i<=m;i++) {
for(int j =1;j<=n;j++) {
int k;
fscanf(file,"%d",&k);
grid[indexFor(i,j)] = k;
}
}
int startX,startY,endX,endY;
fscanf(file,"%d",&startX);
fscanf(file,"%d",&startY);
fscanf(file,"%d",&endX);
fscanf(file,"%d",&endY);
queue<int> x,y;
x.push(1);
y.push(1);
vector<int> visited((m+1)*(n+1),0);
vector<int> queued((m+1)*(n+1),0); // <-- THIS IS WHAT I ADDED
vector<vector<int>> path_track((m+1)*(n+1),vector<int>(2,0));
while(x.size()>0) {
int k = x.front(), l = y.front();
x.pop();
y.pop();
visited[indexFor(k,l)]=1;
cout << "\033[2J\033[H";
cout << "queue size: " << x.size()<<endl;
for(int i=1;i<=m;i++) {
for(int j =1;j<=n;j++) {
if(visited[indexFor(i,j)]==1) cout << "* ";
else {
if(grid[indexFor(i,j)]==0) {
cout << ". ";
} else {
cout << "# ";
}
}
}
cout << endl;
}
usleep(10000);
if(k-1>0) {
if(grid[indexFor(k-1,l)] != 1 && visited[indexFor(k-1,l)]!=1&&!queued[indexFor(k-1,l)]) {
x.push(k-1);
y.push(l);
queued[indexFor(x.back(),y.back())] = 1;
path_track[indexFor(x.back(),y.back())] = {k,l};
}}
if((k+1)<=m) {
if(grid[indexFor(k+1,l)] != 1 && visited[indexFor(k+1,l)]!=1&&!queued[indexFor(k+1,l)]) {
x.push(k+1);
y.push(l);
//cout << "Path_track: "<<x.back() << ", " << y.back() << " : " << k << ", " << l <<endl;
path_track[indexFor(x.back(),y.back())] = {k,l};
queued[indexFor(x.back(),y.back())] = 1;
}}
if(l-1>0) {
if(grid[indexFor(k,l-1)] != 1 && visited[indexFor(k,l-1)]!=1&&!queued[indexFor(k,l-1)]) {
x.push(k);
y.push(l-1);
path_track[indexFor(x.back(),y.back())] = {k,l};
queued[indexFor(x.back(),y.back())] = 1;
}}
if(l+1<=n) {
if(grid[indexFor(k,l+1)] != 1 && visited[indexFor(k,l+1)]!=1&&!queued[indexFor(k,l+1)]) {
x.push(k);
y.push(l+1);
queued[indexFor(x.back(),y.back())] = 1;
path_track[indexFor(x.back(),y.back())] = {k,l};
}}
}
cout << "\033[2J\033[H";
vector<vector<int>> path;
/*
for(int i=1;i<=m;i++) {
for(int j =1;j<=m;j++) {
cout << path_track[indexFor(i,j)][0] << "," << path_track[indexFor(i,j)][1]<< " ";
}
cout << endl;
}
*/
path.push_back({endX,endY});
while(endX!=0&&endY!=0) {
int kx = endX, ky = endY;
endX = path_track[indexFor(kx,ky)][0];
endY = path_track[indexFor(kx,ky)][1];
path.push_back({endX,endY});
}
path.pop_back();
if(path[path.size()-1][0] == startX && path[path.size()-1][1] == startY)
{
for(vector<int> l:path) grid[indexFor(l[0],l[1])] = 8;
for(int i=1;i<=m;i++) {
for(int j =1;j<=n;j++) {
if(grid[indexFor(i,j)]==8) {
cout << "X ";
} else {
if(grid[indexFor(i,j)]==0) {
cout << ". ";
} else {
cout << "# ";
}
}
}
cout << endl;
}
} else {
cout << "No path found\n";
for(vector<int> l:path) grid[indexFor(l[0],l[1])] = 8;
for(int i=1;i<=m;i++) {
for(int j =1;j<=n;j++) {
if(grid[indexFor(i,j)]==8) {
cout << "X ";
} else {
if(grid[indexFor(i,j)]==0) {
cout << ". ";
} else {
cout << "# ";
}
}
}
cout << endl;
}
}
//cout<<path_track[indexFor(2,2)][0]<<","<<path_track[indexFor(2,2)][1]<<endl;
return 0;
}

Printing two-dimensional array

I have this two-dimensial array array[y][x] (where x is horizontal and y vertical):
3 2 0 0 0 0 0 0 0 0
1 4 3 0 0 0 0 0 0 0
2 4 0 0 0 0 0 0 0 0
2 4 0 0 0 0 0 0 0 0
1 3 0 0 0 0 0 0 0 0
4 2 5 1 0 0 0 0 0 0
1 3 0 0 0 0 0 0 0 0
2 3 0 0 0 0 0 0 0 0
2 3 0 0 0 0 0 0 0 0
And I need to print it like this:
3 1 2 2 1 4 1 2 2
2 4 4 4 3 2 3 3 3
3 5
1
How would I do this using c++?
Note that there are no empty lines. If the whole column only has zero's in them, there shouldn't be an endl
You need to iterate over and print out each element. You can flip the elements around by swapping the indices used to get the value out of the array.
#include<iostream>
#include<iomanip>
int gridWidth = 10;
int gridHeight = 10;
int cellWidth = 2;
for (int i = 0; i < gridHeight; i++){
bool anyVals = false;
for (int j = 0; j < gridWidth; j++){
int val = array[i][j]; //Swap i and j to change the orientation of the output
if(val == 0){
std::cout << std::setw(cellWidth) << " ";
}
else{
anyVals = true;
std::cout << std::setw(cellWidth) << val;
}
}
if(anyVals)
std::cout << std::endl;
}
Remember that if you swap i and j then you will need to swap gridWidth and gridHeight.
Just to avoid confusion std::setw(cellWidth) thing is a convenient way to print fixed-width text (like text that must always be two characters long). It takes whatever you print out and adds spaces to it to make it the right length.
Take the transpose of your matrix , make 2 loops(outer and inner ) and print only if the no is greater than zero and print space for every zero. when you go back again to the outer loop ,print new line .
Something like this should help you.
for (int i = 0; i < y; i++)
for (int j = 0; j < x; j++)
if (array[i][j] != 0)
cout << array[i][j];
else
cout << " ";
cout << endl;

Checking if matrix of 1s and 0s are connected - C++

The goal is to create a matrix where all the 0s are connected (touching either up, down, left or right). I generated a 10/19 matrix of 0s and randomly added 1s. Now I want to step through the matrix and change values such that all 0s are connected, but I am struggling with that part. Any help is greatly appreciated!
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main () {
//generate matrix of 0s
int map[10][19] = {{0}};
int a = 10;
int b = 19;
//display matrix
for (int i = 0; i < a; ++i) {
for (int j = 0; j < b; ++j) {
std::cout << map[i][j] << ' ';
}
std::cout << std::endl;
}
cout << "\n" << endl;
//adds 1s to matrix
for (int i = 0; i < a; ++i) {
for (int j = 0; j < b; ++j) {
map[i][j] = 0 + rand() % 2;
}
}
//display matrix
for (int i = 0; i < a; ++i) {
for (int j = 0; j < b; ++j) {
std::cout << map[i][j] << ' ';
}
std::cout << std::endl;
}
cout << "\n" << endl;
First output:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Second output:
1 1 1 0 0 0 0 0 1 1 0 1 0 0 1 1 1 1 0
0 1 1 1 1 0 1 1 0 0 1 1 0 0 1 0 1 1 1
1 1 1 0 1 0 1 1 0 1 0 1 1 1 0 0 0 0 0
0 0 1 0 0 1 0 1 1 1 0 0 1 0 1 1 1 1 0
1 0 1 1 1 0 1 1 1 1 1 0 1 0 0 1 1 0 0
0 0 1 0 0 1 1 1 0 1 0 1 1 0 0 1 1 1 1
1 0 0 1 0 0 0 1 0 0 1 0 1 0 0 0 0 1 0
0 1 1 1 0 1 1 0 1 0 1 0 0 0 1 1 0 0 0
1 1 0 1 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0
0 1 0 0 0 0 1 1 1 1 1 0 1 1 1 0 1 1 0