Function returns a wrong number? - c++

Can anybody help me with this? It gives me a wrong number. matrix[i][j].spath is filled with the correct values but when i return the shortest path between any two nodes it gives me a wrong number. The compiler gives me this
warning: control reaches end of non-void function
But the if-statement where i check whether the end is reached will always perform so the return statement, because i set up the end coordinates in main(). But i noticed when i add return 1 or return anything at the end of the function it gives the correct result. Is this a kind of a rule or what? I have written a functions like this where i had an if-statement and the only return statement in it and it worked without problems. Thanks :)
#include <iostream>
#include <queue>
using namespace std;
struct node
{
int x,y,spath,val;
}v,c;
node mat[100][100];
int dy[] = {-1,1,0,0}, dx[] = {0,0,-1,1}, n, m;
void input()
{
cin >> n >> m;
for (int i=0; i<n; i++) {
for (int j=0; j<m; j++) {
cin >> mat[i][j].val;
mat[i][j].spath = 0;
}
}
}
int shortest_path(node start, node end)
{
queue<node> q;
q.push(start);
mat[start.y][start.x].val = 1;
while (!q.empty())
{
v = q.front();
q.pop();
for (int i=0; i<4; i++) {
c.y = v.y + dy[i];
c.x = v.x + dx[i];
if (c.y == end.y && c.x == end.x) {
return mat[v.y][v.x].spath + 1;
}
else if (c.y >=0 && c.y < n && c.x >=0 && c.x < m && mat[c.y][c.x].val == 0)
{
mat[c.y][c.x].val = 1;
mat[c.y][c.x].spath = mat[v.y][v.x].spath + 1;
q.push(c);
}
}
}
}
int main()
{
node start,end;
start.x = start.y = 0;
end.y = end.x = 4;
input();
cout << shortest_path(start,end) << endl;
return 0;
}

As you noticed, the problem is that it misses a return statement. You may know that it will always go through the return in the if statement, but the compiler doesn't, hence the warning.
You supposed the input was correct, but you should "never trust user input". Never Ever.
There should always be a return statement for all routes the execution might take in your non-void function.

It seems that you are writing BFS.Here's my code:
#include"stdio.h"
#include"string.h"
#include"queue"
using namespace std;
#define N 200
int n,m;
int move[][2]={{0,1},{1,0},{0,-1},{-1,0}};
struct node
{
node(int _x=0,int _y=0)
{
x=_x,y=_y;
}
int x,y; //mark the Coord of the node
};
int data[N][N];//store data.
bool map[N][N]; //mark whether the node is visited.
int input()//input & initialize the array
{
memset(map,false,sizeof(map));
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
int t;
scanf("%d",&t);
data[i][j]=t;
map[i][j]=false;
}
return 0;
}
bool judge(node x)
{
if(x.x<n&&x.x>=0&&x.y<m&&x.y>=0) return true;
return false;
}
int shortest_path(node s,node e)
{
queue<int>dist;//means 'spath' in your code.
int dst=0;
queue<node>q;
q.push(s);
map[s.x][s.y]=true;
dist.push(0);
node v,c;
while(!q.empty())
{
v=q.front();
q.pop();
dst=dist.front();
dist.pop();
for(int i=0;i<4;i++)
{
c.x=v.x+move[i][0];
c.y=v.y+move[i][1];
if(judge(c)&&!map[c.x][c.y])
{
dist.push(dst+1);
q.push(c);
map[c.x][c.y]=true;
if(c.x==e.x&&c.y==e.y)
return dst+1;
}
}
}
return -1;//if the path not found return -1;
};
int main()
{
input();
node s(0,0),e(4,4);
printf("%d\n",shortest_path(s,e));
return 0;
}
the input should be:
n>=5 m>=5 because end point is(4,4).
and an n*m matrix.

About the warning :
Your code is not protected against bad input : if end is outside your n x m grid, or is on a "wall", or if there is no path from start to end your function will exit without executing a return statement.
The compiler has no way of predicting what input will be fed to the function.

Related

Receiving updated value from recursive call

I have a DFS function which collects entry and leave times of vertices. Unfortunately, I am unable to receive a proper value for leave time, because it is not connected with the value from recursive call.
void DFS_visit(int i, vector<int> Adj[], int visited[], int p[], int entry[], int leave[], int t)
{
visited[i] = 1;
entry[i] = t;
cout << i << " ";
for (auto u : Adj[i])
{
if (!visited[u])
{
p[u] = i;
DFS_visit(u, Adj, visited, p, entry, leave, t++);
}
}
leave[i] = t++;
}
It is obviously an auxiliary function, I also have a "main" DFS function:
void DFS(vector<int> Adj[], int n)
{
int visited[n], p[n], entry[n], leave[n];
int t = 0;
for (int i = 0; i < n; i++)
{
visited[i] = 0;
p[i] = -1;
}
for (int i = 0; i < n; i++)
{
if (!visited[i])
{
DFS_visit(i, Adj, visited, p, entry, leave, t);
}
}
Could you please tell me how I am supposed to pass the updated value of leave time to leave[i]? Thanks in advance!

Break error on cout

I'm writing an easy Game Of Life simulator. Everything works smoothly except at the very end, when the result is printed by cout I get a break error. I don't understand why and I would like to ask for your help.
variables
#include <iostream>
using namespace std;
struct cell
{
bool isAlive;
int posX;
int posY;
int numberOfAliveNeighbours;
char group;
};
int cellNumber;
cell *cellTable = new cell[cellNumber];
int numberOfTunrs;
main:
int main()
{
int x;
int y;
int cellCounter = 0;
cin >> x >> y;
cellNumber = x*y;
cin >> numberOfTunrs;
for (int i = 0; i < x; i++)
{
for (int j = 0; j < y; j++)
{
char cellAliveChar;
cin >> cellAliveChar;
if (cellAliveChar == '#')
{
cellTable[cellCounter].isAlive = true;
}
else if (cellAliveChar == '.')
{
cellTable[cellCounter].isAlive = false;
}
cellTable[cellCounter].numberOfAliveNeighbours = 0;
cellTable[cellCounter].group = '#';
cellTable[cellCounter].posX = j;
cellTable[cellCounter].posY = i;
cellCounter++;
}
}
doTurns(x, y);
int result;
result = countGroups();
**cout << result << endl;**
//here is breakpoint
cin >> x;
}
countGroups (idk if it's relevant):
int countGroups()
{
int max = 0;
int current;
int i = 0;
char checkingGroup = 'A';
do
{
current = 0;
for (int j = 0; j < cellNumber; j++)
{
if (cellTable[j].group == checkingGroup + i)
{
current++;
}
}
i++;
if (current > max)
{
max = current;
}
} while (current != 0);
return max;
}
the breakpoint screenshot:
Click to view the screenshot
The problem is cellTable declaration:
int cellNumber;
cell *cellTable = new cell[cellNumber];
Global variables are implicitly initialized with 0 so cellNumber will point to array of 0 size and any attempt to access cellTable items leads to undefined behavior.
It would be better to make all variables local and pass them to functions explicitly. Instead of manually allocating array you should use std::vector, or at least allocate after assigning an appropriate number to cellNumber (after getting x and y values).

std::vector out of range for min-heap: C++

I've neglected to work on this code (or any other coding projects) for a while, so while I know what is basically wrong with the code, I've been having a hard time finding exactly where the vector is going out of range. I've been running gdb on it all morning to no avail. I'm trying to make a min-heap out of a vector "theData" in C++.
#include <iostream>
#include <vector>
#include <algorithm>
using std::vector;
using std::cin;
using std::cout;
using std::swap;
using std::pair;
using std::make_pair;
class HeapBuilder {
private:
vector<int> data_;
vector< pair<int, int> > swaps_;
void WriteResponse() const {
cout << swaps_.size() << "\n";
for (int i = 0; i < swaps_.size(); ++i) {
cout << swaps_[i].first << " " << swaps_[i].second << "\n";
}
}
void ReadData() {
int n;
cin >> n;
data_.resize(n);
for(int i = 0; i < n; ++i)
cin >> data_[i];
}
void makeMinHeap(vector<int> &theData, int i, int n) {
int minIndex;
int left = 2*i;
int right = 2*i + 1;
if (left < n && theData.at(left) < theData.at(i)) {
minIndex = left;
}
else if (right < n && theData.at(right) < theData.at(i)) {
minIndex = right;
}
if (minIndex != i) {
swap(theData.at(i), theData.at(minIndex));
swaps_.push_back(make_pair(i, minIndex));
makeMinHeap(theData, minIndex, n);
}
}
void GenerateSwaps() {
swaps_.clear();
int size = data_.size();
for (int i = (size/2); i >= 0; i--) {
makeMinHeap(data_, i, size);
}
}
public:
void Solve() {
ReadData();
GenerateSwaps();
WriteResponse();
}
};
int main() {
std::ios_base::sync_with_stdio(false);
HeapBuilder heap_builder;
heap_builder.Solve();
return 0;
}
You are not putting in a check for minIndex.
Look what happens when your left<=n and right <=n both fails, most likely when the whole recursion is about to stop, since you just check
minIndex != i
// ^-- default each time is garbage which in case last>n && right>n leaves it garbage
// hence when it comes to
if(minIndex!=i){
// It's actually true where it was suppose to break out n thus throws out_of_range
}
Quick n easy solution would be to add a flagcheck
bool flagcheck = false;
if(){ flagcheck = true; }
else if(){ flagcheck = true; }
if(minIndex!=i && flagcheck){}

Debug on Program about Permutation

Recently I am writing a program to generate a fixed number of permutation of alphabets inputted. For example, I inputted 3, 3, ABC, the program will output ABC, ACB, BAC, according to lexicographical order. But the program cannot get through all the test case and i cant find out where is the bug. Please help.
#include <iostream>
using namespace std;
int used[26], cou = 0, k, n, i;
string output;
string sorting(string x, int y)
{
char temp;
int i, j;
for (i = 0; i < y; ++i)
{
for (j = 0; j < y-1; ++j)
{
if (x[j]-'0' > x[j+1]-'0')
{
temp = x[j];
x[j] = x[j+1];
x[j+1] = temp;
}
}
}
return x;
}
void out(int x, string y)
{
int i;
if (cou == k)
{
return;
}
if (x == n+1)
{
cout << output << endl;
++cou;
}
else
{
for (i = 0; i < n; ++i)
{
if (used[i] == 0)
{
used[i] = 1;
output[x-1] = y[i];
out(x+1, y);
used[i] = 0;
}
}
}
}
int main()
{
char inpi;
string inp, ha;
cin >> n >> k >> inp;
output.resize(n);
for (i = 0; i < 26; ++i)
{
used[i] = 0;
}
inp = sorting(inp, n);
out(1, inp);
}
I am not sure that I understood the question.
Leaving the algorithm aside, you should know that a standard string is able to tell how long is. Therefore the y parameter in sorting is redundant. Use x.size() to find the size.
Another problem is output[x] = y[i];. You did not set output's size: it is zero. Since you are looking for permutations, I assume its size must equal y's size: output.resize( y.size() );.
One last thing: use meaningful identifiers. y may be good for a compiler; for a human, it may define a bad day.
There doesn't seem to be a need to create a global as you have done
string output;
Create a string to capture the output either within main() and pass it by reference to the functions which need them, in this case fill()
or
create it within fill() and return it by value once its populated

C++ does not want a return value

I'm trying some exercise to learn the use of pointers with arrays and functions.
So I tried to code a "strange way" to find out primes within a certain range.
The problem is that the output always add the return value of the function with the algorithm for the primes. if I omit it, it shows is '32767', if I write return *pt, it adds the last number of the range, even if it's not a prime!
Just tried it with number 6: it's not a prime but it pops up!
#include <iostream>
int show_primes(const int * begin, const int * end);
int main()
{
using namespace std;
int i = 0;
int End_Array = 0;
cout << "Write the last number in your range (it always start from number 2)";
cin >> End_Array;
i=End_Array;
int cookies[i];
for(i=-1; i<End_Array; i++)
cookies[i] = i+1;
cout << show_primes(cookies, cookies + End_Array-1);
}
int show_primes (const int * begin, const int * end)
{
using namespace std;
const int * pt;
int z = 0;
for (pt = begin; pt < end; pt++, z=0)
{
for (int n=2; n<=*pt; n++)
if ( *pt%n == 0 )
++z;
if (z==1)
cout << *pt <<endl;
}
return *pt ;
}
Your loop is accessing a value at negative index.
cookies[i] = i+1; //For first iteration, value of i is -1
So for(i=-1; i<End_Array; i++) should be changed to for(i=0; i<End_Array; i++)
Also, you do not need to return from the function as you are printing the values within itself
Although you are using pointers for your learning, a more simpler implementation would be:
#include <iostream>
using namespace std;
void show_primes(int num)
{
bool flag = false;
for (int pt = 2; pt < num; pt++)
{
if ( num%pt == 0 )
{
flag = true;
break;
}
}
if(!flag)
{
cout<<num<<' ';
}
}
int main()
{
int End_Array = 0;
cout << "Write the last number in your range(>2)";
cin >> End_Array;
for(int i=2; i<End_Array; i++)
{
show_primes(i);
}
}
P.S.: Can someone please highlight that is it a bad practice to include std namespace in every functional block as OP has done.(I think it is)
for(i=0; i<End_Array; i++) // Start from zero
cookies[i] = i; //Use i
// Don't use cout
show_primes(cookies, cookies + End_Array-1);