分段错误背包问题

Posted

技术标签:

【中文标题】分段错误背包问题【英文标题】:segmentation fault knapsackproblem 【发布时间】:2020-01-02 11:58:48 【问题描述】:

我用 C++ 编写了这个背包问题解决方案,但是当我运行它时,它给了我分段错误 我已经尝试了一切,我的编译器总是会给我分段错误错误。

#include<iostream>
#include<algorithm>

int knapsack(int v[],int w[],int n,int W)

    int V[n][W];
    for(int i = 0; i<=W;i++)
    
        V[0][i] = 0;
    
    for(int i = 0; i <= n; i++)
        for(int j = 1; j<=W; j++)
        
            if(w[i]<=W)
            
                V[i][j] = std::max(V[i-1][j], v[i]+V[i-1][j-w[i]]);
            
            else
            
                V[i][j] = V[i-1][j];
            

        
    
    return V[n][W];


int main()

    int v[4] = 10,40,30,50;
    int w[4] = 5,4,6,3;
    int n = 3;
    int W = 10;

    std::cout<<"item value:"<<knapsack(v,w,n,W);

【问题讨论】:

有根据的猜测:循环条件通常是counter &lt; length,而不是&lt;=,因为数组的最后一个索引是length - 1 int V[n][W]; 这需要支持可变长度数组,这是C++中的非标准结构。 【参考方案1】:
    不要使用 VLA。数组的大小必须在编译时知道,否则它不是标准的 C++。这些是不可移植的编译器扩展,会带来一些隐性成本。

    数组索引从 0 到 length-1。在你循环中

    for(int i = 0; i<=W;i++)
    

    i 可以到达W,然后V[0][W] 越界导致seg 错误。你必须使用&lt; 而不是&lt;=

    for(int i = 0; i < W; i++)
    

    n 应该是 4,如果它是用来表示数组的大小,std::vector 会让你的生活更轻松,因为向量知道它的大小

    一般来说,在这个时代根本不要使用 C 风格的数组或原始指针,而是使用 std::vector。

【讨论】:

【参考方案2】:
int V[n][W];
for(int i = 0; i<=W;i++)

    V[0][i] = 0;

请注意,V 的索引从 V[0][0]V[0][W-1]。您的 for 循环将尝试读取 V[0][W]

同样的错误在其他地方重复出现。您的 for 循环中的结束条件应该是 &lt;(严格小于)而不是 &lt;=(小于或等于)。

【讨论】:

以上是关于分段错误背包问题的主要内容,如果未能解决你的问题,请参考以下文章

我的背包代码输出错误?

dp 的背包问题让我的答案错误

0-1 整数背包返回错误答案(动态规划)

背包分支定界错误结果

loop-malloc.c 的向量中的分段错误:没有这样的文件或目录

laravel - 背包 - addFilter 自定义查询