Может ли кто-нибудь помочь мне в этом? Это дает мне неправильный номер. matrix [i] [j].spath заполняется правильными значениями, но когда я возвращаю кратчайший путь между любыми двумя узлами, он дает мне неправильный номер. Компилятор мне это дает
предупреждение: управление достигает конца не-void функции
Но if-statement, где я проверяю, достигнут ли конец, всегда будет выполняться так, чтобы оператор return, потому что я установил конечные координаты в main(). Но я заметил, когда добавляю return 1 или возвращаю что-нибудь в конце функции, он дает правильный результат. Это что-то вроде правила или что? Я написал такие функции, когда у меня был оператор if и единственный оператор return, и он работал без проблем. Благодаря :)
#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;
}
О предупреждении:
Ваш код не защищен от неправильного ввода: если end
находится вне вашей сетки nxm
или находится на "стене", или если нет пути от start
до end
ваша функция выйдет без выполнения оператора return.
Компилятор не может предсказать, какой вход будет передан функции.
Как вы заметили, проблема в том, что он пропускает оператор return. Вы можете знать, что он всегда будет проходить через return в выражении if, но компилятор не делает этого, следовательно, предупреждение. Вы предположили, что ввод был правильным, но вы должны "никогда не доверять пользовательскому вводу". Никогда.
Всегда должен быть оператор return для всех маршрутов, выполнение которых может выполняться в вашей не-void функции.
Кажется, что вы пишете BFS. Вот мой код:
#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;
}
вход должен быть: n> = 5 m> = 5, потому что конечная точка (4,4). и матрица n * m.