You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

网格两点间路径坐标获取方法及代码报错求助

网格两点间路径坐标获取方法及代码报错求助

你好呀!看你说已经能判断矩阵两点间是否存在路径,但卡在获取具体路径坐标上,一开始考虑用链表来记录相邻节点,后来尝试用BFS的思路实现但遇到了编译错误,我来帮你分析下问题出在哪,再给你修正后的可行方案~

错误原因分析

  • 第一个错误:std::queue没有下标运算符
    你提到的unvisitedNeighbours[0].pMain报错,是因为std::queue是队列容器,它只支持front()/back()访问队首/队尾元素,不支持用[]直接下标访问,应该是你调试时误写了这段代码,正常逻辑里队列不能这么用哦。

  • 第二个错误:this指针使用不当
    报错里的this->parent->parent...,this只能在类的非静态成员函数里使用,如果是在全局函数或者main里写了这段,肯定会报错,这应该也是调试时的误写,记得this的使用范围就好。

你的代码里还有这些隐藏问题

  1. 结构体node的构造函数错误:你在构造函数里写了int index = _index;,这是定义了一个局部变量,根本没给成员变量index赋值,应该改成index = _index;或者用初始化列表更规范。
  2. 节点初始化语法错误:node Node(node(make_pair(0, 0), make_pair(-1, -1), 0));这行是错误的,直接写node Node(make_pair(0, 0), make_pair(-1, -1), 0);就可以,不需要嵌套node()。
  3. 路径回溯逻辑错误:你用index关联父节点的逻辑有问题,而且直接修改原数组标记已访问,会破坏输入数据,最好用单独的访问矩阵。
  4. 越界判断顺序错误:你先判断arr[a][b] != -1再判断坐标是否合法,这样如果a或b越界,访问arr[a][b]会直接导致数组越界崩溃,应该先判断坐标是否在矩阵范围内。

修正后的完整代码

#include <vector>
#include <iostream>
#include <queue>
#include <utility>

using namespace std;

const int row = 5;
const int col = 5;

struct node {
    pair<int, int> pMain;
    pair<int, int> parent;
    int index;

    // 用初始化列表正确初始化成员变量
    node(pair<int, int> _p, pair<int, int> _parent, int _index) 
        : pMain(_p), parent(_parent), index(_index) {}
};

// 查找从(0,0)到(row-1, col-1)的路径,并输出路径坐标
bool findPath(int arr[row][col]) {
    // 四个方向:右、左、下、上
    int dir[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};

    // 单独的访问标记矩阵,避免修改原输入数组
    bool visited[row][col] = {false};
    queue<node> unvisitedNeighbours;
    vector<node> paths;

    // 初始化起点节点:坐标(0,0),父节点(-1,-1),索引0
    node startNode(make_pair(0, 0), make_pair(-1, -1), 0);
    unvisitedNeighbours.emplace(startNode);
    paths.push_back(startNode);
    visited[0][0] = true;

    while (!unvisitedNeighbours.empty()) {
        node current = unvisitedNeighbours.front();
        unvisitedNeighbours.pop();

        // 到达终点,回溯路径并输出
        if (current.pMain == make_pair(row - 1, col - 1)) {
            cout << "找到的路径坐标(从终点到起点):" << endl;
            pair<int, int> currPos = current.pMain;
            // 回溯父节点直到起点
            while (currPos.first != -1 && currPos.second != -1) {
                cout << "(" << currPos.first << ", " << currPos.second << ")" << endl;
                // 在paths中查找父节点对应的节点
                for (const auto& n : paths) {
                    if (n.pMain == currPos) {
                        currPos = n.parent;
                        break;
                    }
                }
            }
            // 想要从起点到终点的顺序,可以把路径存到临时vector里再反转输出
            return true;
        }

        // 遍历四个方向的邻居
        for (int i = 0; i < 4; ++i) {
            int newRow = current.pMain.first + dir[i][0];
            int newCol = current.pMain.second + dir[i][1];

            // 先判断坐标合法性,再判断是否可访问
            if (newRow >= 0 && newRow < row && newCol >= 0 && newCol < col 
                && !visited[newRow][newCol] && arr[newRow][newCol] != -1) {
                visited[newRow][newCol] = true;
                // 新节点的索引是paths当前的大小(因为马上要push进去)
                node newNode(make_pair(newRow, newCol), current.pMain, paths.size());
                paths.push_back(newNode);
                unvisitedNeighbours.emplace(newNode);
            }
        }
    }

    // 没有找到有效路径
    return false;
}

int main() {
    int arr[row][col] = {
        {0,  0, 0,  -1, 0},
        {-1, 0, 0,  -1, -1},
        {0,  0, 0,  -1, 0},
        {-1, 0, 0,  0,  0},
        {0,  0, -1, 0,  0}
    };

    if (findPath(arr)) {
        cout << "\n路径存在!" << endl;
    } else {
        cout << "不存在有效路径!" << endl;
    }

    return 0;
}

代码关键说明

  1. 访问标记优化:用单独的visited矩阵标记已访问节点,不会破坏原输入数组,更安全。
  2. 构造函数修正:用初始化列表初始化成员变量,避免局部变量覆盖成员变量的低级错误。
  3. 坐标判断顺序:先判断新坐标是否在矩阵范围内,再判断是否可访问,彻底避免数组越界问题。
  4. 路径回溯逻辑:通过节点的parent坐标回溯,从终点倒推回起点,如果你需要从起点到终点的顺序,可以把路径存入临时vector后反转输出。
  5. 队列规范使用:严格遵循队列的FIFO特性,用front()取队首、pop()弹出,避免错误用法。

补充:获取所有可能路径的思路

如果你需要获取所有可能的路径,而不仅仅是一条最短路径,BFS就不太合适了,推荐用DFS(深度优先搜索):

  • 递归遍历每个可访问的邻居节点
  • 每次访问时记录当前路径
  • 到达终点时将当前路径保存到结果列表中
  • 回溯时取消当前节点的访问标记,以便其他路径可以再次访问它

你可以写一个递归函数,参数包括当前坐标、当前路径、访问标记、结果列表,这样就能收集到所有合法路径啦。

备注:内容来源于stack exchange,提问作者Fox1942

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.23 10:34:30