递归路径查找,直到除法结果为1

时间:2019-01-27 04:02:06

标签: c++ recursion

我正在尝试解决类似这样的递归练习。 假设您有一个nxm的矩阵,其中有这样的整数(仅作为示例):

1 1 1 5 2 2 3 5 2 1 3 1 1 1 5 1 1 5 1 1

我想找到一条路径(从任何地方开始),给定一个数字n,每一步n都会变化n /(number_at_that_position),并且当n = 1时该路径停止。

我不是在寻找所有路径,我只是在寻找路径。 因此,如果使用符号映射路径,则最终会得到一个矩阵

> > V - * - - V > ^ - - V ^ - - - > ^ -

其中“>”表示向右移动,“ <”表示向左移动,“ ^”表示向上移动,“ V”表示向下移动。一旦n变为1,我们插入“ *”表示路径结束。 最重要:路径必须是连续的,您不能访问以前访问过的地方。 更重要的是:找到路径的函数必须是递归的。 如果未找到任何路径,则代码退出并显示一条消息,指出未找到任何路径。

到目前为止,我为路径查找提供了以下代码。我使用过来自不同地方的想法,但是其中一个就是Recursively finding a path through a maze c++

bool path_print(vector<vector<int> > &P,  size_t line, size_t col, vector<vector<char> > &A, int n) {
  if (line < 0 || line > P.size() || col < 0 || col > P[0].size()) {
    return false;
  }
  if (A[line][col] != '-') {
    return false;
  }
  if (n == 1) {
    A[line][col] = '*';
    return false;
  }
  printf("n = %d, line = %zu, col = %zu\n", n, line, col);
  n = n/P[line][col];
  if (path_print(P, line, col+1, A, n) == true){
    A[line][col] = '>';
    return true;
  } else if (path_print(P, line-1, col, A, n) == true) {
    A[line][col] = '^';
    return true;
  } else if (path_print(P, line+1, col, A, n) == true){
    A[line][col] = 'V';
    return true;
  } else if (path_print(P, line, col-1, A, n) == true){
    A[line][col] = '<';
    return true;
  } 
  return true;
}

P是包含值的向量 A是存储路径的char向量 n是您要探测的实际数字

我已经为此工作了一段时间,被困住了。此代码无法正常工作。任何建议或帮助将不胜感激。 预先谢谢你

1 个答案:

答案 0 :(得分:0)

在您的代码中:

if (line < 0 || line > P.size() || col < 0 || col > P[0].size())

错误的原因是:

  • 允许使用索引P.size()P[0].size(),在链接的原始代码中,使用size - 1进行比较
  • line size_t,所以line < 0毫无意义,对于 col

可以是:

bool path_print(vector<vector<int> > &P,  int line, int col, vector<vector<char> > &A, int n) {
   if (line < 0 || line >= (int) P.size() || col < 0 || col >= (int) P[0].size())

或先检查 col line ,然后对其进行 +1 -1 致电以免发生任何问题,包括溢出。


但这不足以解决您的问题,因为您对链接代码的其他更改是错误的:

  • 您在递归调用之后而不是之前修改
  • 之后您不将A单元格重置为“-”
  • 当您找到出口(在您的情况下, n 为1)时,您返回 false 而不是 true ,因此您继续进行搜索,并在另一步
  • 之后检查 n 的值太晚了
  • 在函数末尾,您返回 true 而不是 false

请注意,除法后 n 为0时继续搜索是没有用的


if (f() == true)是多余的,if (f())就足够了


修改代码的解决方案是:

#include <iostream>
#include <vector>
using namespace std;

bool searchPath(const vector<vector<int> > & P, 
                size_t line, size_t col,
                vector<vector<char> > &A,
                int n) {
  if (A[line][col] != '-') {
    return false;
  }

  n = n/P[line][col];

  if (n == 1) {
    A[line][col] = '*';
    return true;
  }
  if (n == 0)
    return false;

  A[line][col] = '>';
  if ((col != (P[0].size() - 1)) && searchPath(P, line, col+1, A, n)) {
    return true;
  } 

  A[line][col] = '^';
  if ((line != 0) && searchPath(P, line-1, col, A, n)) {
    return true;
  }

  A[line][col] = 'V';
  if ((line != (P.size() - 1)) && searchPath(P, line+1, col, A, n)){
    return true;
  }

  A[line][col] = '<';
  if ((col != 0) && searchPath(P, line, col-1, A, n)){
    return true;
  } 

  A[line][col] = '-';
  return false;
}

int main(int argc, char ** argv)
{
  vector<vector<int> > P;
  vector<vector<char> > A;

  // fill vectors

  int lines, columns;

  cout << "number of lines and columns : ";

  if (!((cin >> lines) && (cin >> columns) && (lines > 0) && (columns > 0))) {
    cout << "invalid sizes" << endl;
    return -1;
  }

  P.resize(lines);
  A.resize(lines);

  cout << "enter maze" << endl;
  for (int i = 0; i != lines; ++i) {
    P[i].resize(columns);
    A[i].resize(columns);
    for (int j = 0; j != columns; ++j) {
      int v;

      if (!(cin >> v) || (v < 1)) {
        cout << "invalid input : " << v << endl;
        return -1;
      }
      P[i][j] = v;
      A[i][j] = '-';
    }
  }

  int n;

  cout << "enter n : ";

  if (!(cin >> n) || (n <= 0)) {
    cout << "invalid value of n" << endl;
    return -1;
  }

  // search a way from all cells
  for (size_t l = 0; l != (size_t) lines; ++l) {
    for (size_t c = 0; c != (size_t) columns; ++c) {
      if (searchPath(P, l, c, A, n)) {
        // found
        cout << "found from cell line " << l << " column " << c << endl;

        for (l = 0; l != (size_t) lines; ++l) {
          for (c = 0; c != (size_t) columns; ++c) {
            cout << A[l][c] << ' ';
          }
          cout << endl;
        }

        return 0;
      }
    }
  }

  cout << "no solution" << endl;
  return 0;
}

示例:

number of lines and columns : 4 5
enter maze
1 1 1 5 2
2 3 5 2 1
3 1 1 1 5
1 1 5 1 1
enter n : 200
found from cell line 0 column 0
> > > > V 
- * - - V 
- ^ < < V 
- - - ^ < 

number of lines and columns : 4 5
enter maze
1 1 1 5 2
2 3 5 2 1
3 1 1 1 5
1 1 5 1 1
enter n : 999999
no solution