动态规划算法问题C++和Python实现时结果的差异?
Posted
技术标签:
【中文标题】动态规划算法问题C++和Python实现时结果的差异?【英文标题】:The difference in results when the dynamic planning algorithm problem C++ and Python are implemented? 【发布时间】:2020-04-27 02:12:42 【问题描述】:在绝地求生者中,盔甲和防弹衣分为三个等级,分别记录为1,2,3。每次只能捡起自己没有的,或者把低等级的装备升级到高等级,问一下从无到有到“护甲3级防弹甲3级护甲”有多少升级路线?当前状态由有序数量的对(防弹衣,盔甲)表示,两者的值都为 0-3,例如(0,0)->(0,1)->(0,3)->(3,3) 作为升级策略。
理论上是4*4的数组,不知道为什么python可以实现4*4的数组,但是c++必须写成int[4][4]即5*5的数组结果是对,int[3][3] 计算错误? (结果是最后一个元素,也就是106)
蟒蛇:
dp = [[1,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]]
for i in range(4):
for j in range(4):
for m in range(j):
dp[i][j] += dp[i][m]
for m in range(i):
dp[i][j] += dp[m][j]
dp
输出:106(正确答案) c++:
#include<iostream>
int dp[3][3];
int main ()
dp[0][0] = 1;
for (int i = 0; i <= 3; i++)
for (int j = 0; j <= 3; j++)
for (int m = 0; m < i; m++)
dp[i][j] += dp[m][j];
for (int m = 0; m < j; m++)
dp[i][j] += dp[i][m];
std::cout<<dp[3][3]<<std::endl;
输出:1495(worng!但我不知道为什么?为什么 c++ 中的输出错误?)
【问题讨论】:
快速回答——C++ 和 Python 是两种不同的语言。这就像问为什么法语有 3 个重音符号,而西班牙语有一个。 您的 C++ 代码具有未定义的行为,因为result
应该返回一个 int 但它永远不会返回。很明显,两个程序中最里面的两个循环是不同的。
【参考方案1】:
好的,找到了。您的问题是您使用大小为 3x3 的数组,就好像它大小为 4x4。 一个工作版本:
#include<iostream>
int dp[4][4];
int main ()
dp[0][0] = 1;
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
for (int m = 0; m < j; m++)
dp[i][j] += dp[i][m];
for (int m = 0; m < i; m++)
dp[i][j] += dp[m][j];
std::cout<<dp[3][3]<<std::endl;
重要的变化是 int dp[3][3];
到 int dp[4][4];
。这样,您上面的代码就可以工作了。
没有它,您会越界访问数组,这是未定义的行为。 1495 只是编译器如何解释您的代码的结果,但由于它是 UB,因此任何结果都是有效的。这就是 UB 的欺骗性 - 它通常看起来像是在做一些合理的事情,让它看起来像是你的算法中的一个错误,而实际上并非如此。
我在实验时做了一些进一步的小改动。一种是切换两个内部 for 循环,但那一个不是必需的。我还将<= 3
更改为< 4
,因为这是更常见的样式,但显然也不需要。
为了将来,熟悉使用调试器,或在步骤之间打印出您的结果。如果你有工作的 phyton 代码,你可以在那里做同样的事情,然后比较两个程序的行为。但是请注意,在您的情况下,结果可能看起来很奇怪 - 我在实验时这样做了,结果很有趣,请参阅 http://www.cpp.sh/8aufco 。尽管循环将变量 i 限制为 3,但变量 i 运行到 257。我不知道为什么会这样 - 只是 UB 的结果。
您可能需要考虑将原始数组更改为 std::vector
或 std::array
,但我暂时保留了它。
您的 main 应该 return 0;
作为一个好的做法,尽管它可以按原样工作。
您不应该在 C++ 中使用任何全局变量,就像使用 dp
一样。只需在您的 main(或您以后使用它的任何地方)中声明它。全局变量是错误的一个简单来源(注意常量很好)。
【讨论】:
非常感谢,我发现我犯了一个愚蠢的错误。感谢您提供这些规范和建议,再次感谢您 @zhuowei 不要把它称为愚蠢的错误。看起来更像是你忽略的东西。一直发生在我身上。这样的东西很难调试,我偶然发现了它。以上是关于动态规划算法问题C++和Python实现时结果的差异?的主要内容,如果未能解决你的问题,请参考以下文章
详细实例说明+典型案例实现 对动态规划法进行全面分析 | C++