此代码应完美运行并提供正确的结果,但事实并非如此。我使用调试器,一切都很好。在函数返回之前,c.i
和c.j
具有正确的值。我确保始终在开始和结束之间有一条路径,这不是问题所在。 path
和vis
数组也填充了正确的值。所以唯一的问题是它何时返回。它给出了随机的大数字。它仅在我在函数末尾放置一个return语句时才有效。但是我可以创建一个只有一个返回语句放在if
子句中的函数,它可以工作。是否有某种规则,所以函数末尾必须有任何返回语句?为了测试它,我输入1x的3x3二维数组。任何解决方案?
编辑:我在ideone
上运行它,它在函数末尾没有return语句。我的一个朋友也在他的电脑上测试它也工作。我在Windows 7上使用代码块。问题是什么?
#include <iostream>
#include <string>
#include <queue>
#include <vector>
#include <iomanip>
#include <algorithm>
#include <cmath>
using namespace std;
struct crd {
int i,j;
};
bool vis[50][50];
int map[50][50];
int path[50][50];
int di[4] = {1,-1,0,0};
int dj[4] = {0,0,1,-1};
int bfs(crd start, crd end, int n, int m)
{
queue<crd> q;
crd t,c;
q.push(start);
vis[start.i][start.j] = 1;
path[start.i][start.j] = 0;
while (!q.empty()) {
t = q.front();
q.pop();
for (int i=0; i<4; i++) {
c.i = t.i + di[i];
c.j = t.j + dj[i];
if (c.i >= 0 && c.j >= 0 && c.i < n && c.j < m) {
if (map[c.i][c.j] != -1 && vis[c.i][c.j] != 1) {
q.push(c);
vis[c.i][c.j] = 1;
path[c.i][c.j] = path[t.i][t.j] + 1;
if (c.i == end.i && c.j == end.j)
return path[end.i][end.j];
}
}
}
}
// if i put this: return path[end.i][end.j]; it works
}
int main()
{
for (int i=0; i<3; i++) {
for (int j=0; j<3; j++)
cin >> map[i][j];
}
crd s,e;
s.i = s.j = 0;
e.i = e.j = 2;
int sp = bfs(s,e,3,3);
cout << sp << endl;
return 0;
}
答案 0 :(得分:1)
编译器是非常基础的 - 它无法知道你的函数总是会在if
里面if
内的if
里面返回for
内的while
在{{1}}循环内循环。所以它会警告你,你可能不会从函数中返回任何内容。最简单的解决方法是在最后返回适当的值,并且只在你现在返回的点之外在循环之外中断。
答案 1 :(得分:1)
如果您声明一个非void
返回类型的函数,则此函数应返回一个值。如果执行到达函数的末尾,并且那里没有return <value>;
语句,则函数的结果将是未定义的。
答案 2 :(得分:1)
当你“脱离函数的边缘”时,返回值是未定义的(意味着它可以是任何东西,包括对你返回的类型无效的值)。
所以,每个函数最后都应该有一个返回值。或者某种方式说“我没想到到这里,现在停下来”,如果这是合适的事情(例如,你在寻找列表中的某个东西,并且你不希望找不到它,那么有东西打印“我找不到,期望。停止......”然后退出程序)。
如果你找不到end.i
和end.j
,我不完全确定返回的是什么,但你肯定应该返回SOMETHING。
答案 3 :(得分:1)
你有两个错误。
在返回值的函数末尾没有return
语句,但如果永远无法到达函数的末尾,则仅。在这种情况下,您的搜索算法可能无法找到路径(当然取决于输入数据的内容),然后外部循环将终止而不会执行return
语句。在while循环之后,您必须有另一个return
语句,以说明这种可能性。它应不返回path[end.i][end.j];
而应返回一个特殊值,表示搜索失败。这是编译器检测到并告诉您的错误。
在您的广度优先搜索逻辑中某处出现错误,即使存在 ,也会导致找不到路径。您需要自己调试。