【问题标题】:Changing function argument to global variable causes unexpected results将函数参数更改为全局变量会导致意外结果
【发布时间】:2021-06-05 18:15:18
【问题描述】:

我正在解决回溯问题。我必须构造一个长度为 n 的排列,使得每个相邻元素的总和都是素数。排列是循环的,最后一个元素与第一个元素相邻。请注意,所有有效的排列都应以 1 开头。

void recurse(int i, int prev, int n, vector<int> prime_ring) {
  if (i == n) {
    prime_ring.insert(prime_ring.begin(), 1);
    
    if (!is_prime[prime_ring.back() + 1])
      return;
      for (auto data : prime_ring)
        cout << data << " ";
      cout << "\n";
    
    prime_ring.clear();
    return;
  }
  for (int next = 2; next <= n; next++) {
    if (!seen[next] && is_prime[prev + next]) {
       prime_ring.push_back(next);
       seen[next] = true;
       recurse(i + 1, next, n, prime_ring);
       seen[next] = false;
       prime_ring.pop_back();
      
    }

  }
}

上面的代码正确地生成了想要的排列。例如对于 n = 4。排列应该是

1 2 3 4 
1 4 3 2 



void recurse(int i, int prev, int n) {
  if (i == n) {
    prime_ring.insert(prime_ring.begin(), 1);
    
    if (!is_prime[prime_ring.back() + 1])
      return;
      for (auto data : prime_ring)
        cout << data << " ";
      cout << "\n";
    
    prime_ring.clear();
    return;
  }
  for (int next = 2; next <= n; next++) {
    if (!seen[next] && is_prime[prev + next]) {
       prime_ring.push_back(next);
       seen[next] = true;
       recurse(i + 1, next, n);
       seen[next] = false;
       prime_ring.pop_back();
      
    }

  }
}

prime_ring 更改为全局向量会导致运行时错误。这个问题发生在我身上很多次,我没有意识到出了什么问题。我不知道全局向量与函数参数向量之间的区别。

【问题讨论】:

  • 每次调用recurse 时,都会创建prime_ring 的新副本(按值传递)。对于全局prime_ring,只有一个。所以算法不同。
  • "将 prime_ring 更改为全局向量,会导致运行时错误。"然后不要那样做。您已经有了一个可行的解决方案。
  • prime_ring.clear();为什么找到解决方案后要清除状态?
  • @Code-Apprentice 实际上我的第一种方法是全局方法。这就是我问这个问题的原因。

标签: c++ algorithm recursion backtracking


【解决方案1】:

我不知道全局向量与函数参数向量之间的区别。

不同之处在于,当您将vector 作为参数传递时,vector 会被复制。另一方面,当你使用全局变量时,只有一个`vector。

这里的解决方案是不要使用全局变量,因为你有一个工作函数。

【讨论】:

    【解决方案2】:

    假设你在线

    recurse(i + 1, next, n);
    

    在哪里i == n - 1

    假设当你进入recurse函数时,is_prime[prime_ring.back() + 1]true

    然后你调用prime_ring.clear();,然后返回。

    之后,您拨打prime_ring.pop_back();

    如果您尝试从空向量pop_back() 会发生什么?好吧,可能会发生不好的事情(即Undefined Behaviour

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多