【问题标题】:Segmentation fault in recursive program递归程序中的分段错误
【发布时间】:2020-11-30 03:35:02
【问题描述】:

我在做硬币问题,问题是这样说的,

给定一组硬币值coins = {c1, c2,..., ck} 和一个目标总和 钱n,我们的任务是用尽可能少的硬币来形成总和n 可能。

假设您有 9 美元,并且您有一组 {6,5,1},那么,最小数量。 9 美元的总和/零钱将是( 6+1+1+1=9),即4

我尝试使用这个公式递归地做:

solve(x) = min( solve(x−6)+1, solve(x−5)+1, solve(x−1)+1 )

,但我不知道为什么我的代码中出现分段错误。

网上有很多代码,但我想知道我在这里做错了什么,我是递归新手,请帮助我,代码在这里:

//my code

#include<bits/stdc++.h>
using namespace std;
int solve (int x, int a[], int n)
{
  if (x < 0)
    {
      return INT_MAX;
    }
  if (x == 0)
    {
      return 0;
    }
  int best = INT_MAX;
  for (int i = 0; i < n; i++)
    {
      best = min (best, solve (x - a[i], a, n) + 1);
    }
  return best;
}

int main ()
{
int a[] = { 6, 5, 1 };
int x = 9;
int n = 3;
cout << solve (x, a, n);
  return 0;
}

【问题讨论】:

  • 你试过调试你的代码吗?
  • 立即引起了我的注意:您从未在递归函数中触摸过a——感觉不对。
  • solve (x - i, a, n) 应该是 solve (x - a[i], a, n)。但可能还有其他一些问题。 solve 在某些情况下返回 INT_MAX。你给它加1。你知道会发生什么吗?对于有符号值,行为未定义。
  • @ThomasSablik 其实this 有一个不错的调试器。

标签: c++ recursion segmentation-fault coin-change


【解决方案1】:

代码取自:https://www.geeksforgeeks.org/find-minimum-number-of-coins-that-make-a-change/

    #include <iostream>
    using namespace std;
    
    int minCoins(int coins[], int m, int amount) {
        if (amount == 0) return 0;

        int res = INT_MAX;

        for (int i = 0; i < m; i++) {
            if (coins[i] <= amount) {
                int sub_res = minCoins(coins, m, amount - coins[i]);

                if (sub_res != INT_MAX && sub_res + 1 < res) { // avoid overflow 
                    res = sub_res + 1;
                }
            }
        }
        return res;
    }

    int main() {
        int coins[] = { 6, 5, 1 };
        int amount = 9;
        cout << "Min coins is " 
             << minCoins(coins, sizeof(coins) / sizeof(coins[0]), amount) 
             << endl;
        return 0;
    }

关于问题:

  1. 您的分段错误来自以下行: best = min (best, solve (x - i, a, n) + 1); 原因是:x-i 将始终为您提供相同的值,因此如果您在没有调试的情况下运行程序,您的程序会崩溃。所以不要尝试调试它,因为看到这个崩溃需要很多时间。 对于初学者,请更改为:best = min (best, solve (x - a[i], a, n) + 1);

  2. 修复第 1 节后,if 情况:if (x &lt; 0) return INT_MAX; 将导致问题,并且将始终返回相同的值,即:-INT_MAX。所以你需要再次检查“if case”。

  3. 你尝试实现的算法不正确,请看这个算法的伪代码:

     minchange(M):
       if M = 0:
         return 0
       v <- infinity
       for c in denominations <= M:
          v <- min { minchange(M - c) + 1, v }
       return v
    
  4. 更好地使用:sizeof(a) / sizeof(a[0]) 而不是 int n = 3

【讨论】:

  • 谢谢你,谢谢你,非常感谢......它真的帮助了我 :-),那个 [i] 事情是一个打字错误,我后来更正了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-01
  • 2017-01-11
  • 2017-06-05
  • 2018-03-30
相关资源
最近更新 更多