C++ 程序为某些输入抛出正确的答案,而为其他输入抛出错误的答案。我怀疑数据类型溢出
Posted
技术标签:
【中文标题】C++ 程序为某些输入抛出正确的答案,而为其他输入抛出错误的答案。我怀疑数据类型溢出【英文标题】:C++ program throws right answers for certain inputs and wrong for others. I suspect datatype overflow 【发布时间】:2012-11-20 04:13:33 【问题描述】:我一直在尝试解决涉及组合学和动态编程的编程挑战。
click here to read the problem
好消息是我已经解决了它,但是对于某些输入,程序会抛出错误的答案。
程序将两个数字作为输入。
让w = argv[1]
,h = argv[2]
我会用伪数学的方式来写它以便于表示
例如下面的“公式”表示我的程序接受两个参数:w和h,输出为x
T(w,h) = x
我将用T(w,h)
表示理论结果,用R(w, h)
表示我的程序结果。我 100% 确定 T(w, h)
永远是正确答案。
我们走吧:
T(10, 10) = 2
R(10, 10) = 2
T(11, 10) = 2
R(11, 10) = 288
** 结果不同 **
T(12, 10) = 4
R(12, 10) = 4
T(13, 10) = 4
R(13, 10) = 4
T(14, 10) = 66
R(14, 10) = 66
T(15, 10) = 290
R(15, 10) = 290
T(20, 10) = 9594
R(20, 10) = 98826
结果不同
T(25, 10) = 419854
R(25, 10) = 419854
T(30, 10) = 94082988
R(30, 10) = 94082988
T(35, 10) = 5578404294
R(35, 10) = 1283436998
从现在开始,结果总是不同的
T(36, 10) = 19730715436
R(36, 10) = 18446744071965430572
数据类型溢出?
T(37, 10) = 19730715436
R(37, 10) = 18446744071965430572
T(38, 10) = 73368404198
R(38, 10) = 393345822
这个结果比上一个小,应该比上一个大。
T(39, 10) = 287780277370
R(39, 10) = 17468538
T(40, 10) = 287780277370
R(40, 10) = 17468538
T(41, 10) = 1095232487336
R(41, 10) = 15826856
T(42, 10) = 4013757692218
R(42, 10) = 18446744071672822074
再次上升。花费大量时间来计算
我想这对于黑盒测试来说已经足够了,现在让我们看看算法和实际代码。
第一个参数乘以 2,除以 3 并转换为整数。
例如
argv1 = 20
20*2 = 40
40/3 = 13 整数除法
该值被传递给给我带来问题的函数。
让iNormalizedWidth
成为那个值。
如果iNormalizedWidth
是奇数,程序会一直给我一个错误的答案。
只给我以下数字的错误答案:
11、20、25、29、35 - 48。
(48 是我的程序将处理的最大值)。
这是我写的函数:
typedef long long int int64;
#define BLOCK_A = 2;
#define BLOCK_B = 3;
/* main function, more macros, prototypes of other functions and
irrelevant information for the scope of my question */
vector< vector<int64> > iTileBricks(int iWidth)
int iK, i, j, iMaxIterations, iEvenWidth, iOffset;
vector<int64> viBrickRange;
vector< vector<int64> > viBrickWall;
vector< vector<int64> > viResult;
iEvenWidth = iWidth % 2;
iK = (int)(iWidth/2); // The amount of all possible combinations that follow the pattern nCr(iN-i,2i)
iMaxIterations = iK/3 + 1; // By dividing all the possible combinations by 3, I am finding out how the maximum amount of iterations
for(i = 0; i < iMaxIterations; i++)
iOffset = 2*i + iEvenWidth;
vector<bool> vAux(iK-i); // Creating a iK - i long vector. Test Case:
// Let dOriginalPanelWidth = 48
// iPanelWidth = 32
// iK = iPanelWidth/2 = 16
// iMaxIterations = iK/3 ~= 5
// iK - i = 16 - i Where 1 <= i <= 5
// For the first iteration of i the value of vAux will be:
if(iOffset <= iK-i)
fill(vAux.begin() + iOffset, vAux.end(), true); // For the first iteration of i the value of vAux will be:
// vAux = [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
do // In this block of code I'm generating all the possible layouts of bricks that can build
for(j = 0; j < iK-i; j++) // a wall of 48" (or any value of width where 3 <= width <= 48 and (width % 1/2) == 0).
if(vAux[j] == false)
viBrickRange.push_back(j); // Generating n-tuples with all possible combinations
viBrickWall.push_back(viBrickRange);
viBrickRange.clear();
while(next_permutation(vAux.begin(), vAux.end()));
for(unsigned int a=0; a < viBrickWall.size(); a++)
vector<int64> viTmp(iK-i);
fill(viTmp.begin(), viTmp.end(), BLOCK_A);
for(unsigned int b = 0; b < viBrickWall[a].size(); b++)
viTmp[viBrickWall[a][b]] = BLOCK_B;
viResult.push_back(viTmp);
viTmp.clear();
viBrickWall.clear();
vAux.clear();
return viResult;
我找到了一个用python写的程序,后面的函数只不过是从python函数到C++的一个移植而已。如果有帮助,仅供参考:
def all_single_rows(width):
result = []
n = width / 2
width_parity = width % 2
for i in range(n/3 + 1):
for bits in combinations(range(n-i), 2*i + width_parity):
s = [2] * (n-i)
for bit in bits:
s[bit] = 3
result.append(s)
return result
这是一个相当大的功能(和问题),但我整天都在尝试调试它,但我无法提出解决方案。
生成最终值的计算更多,但这是导致其他函数失败的函数。
我想知道关于为什么某些输入的任何理论,答案猛增,然后又回来了。
当我将我的函数与用 python 编写的函数并排比较时 对于某些输入,输出是相同的,而对于其他一些输入(如上所示),输出是不同的。
任何帮助将不胜感激。
非常感谢!
【问题讨论】:
什么是all_single_rows(7)
?
这是一个用python编写的函数,我想移植到C++
不,不是“什么是all_single_rows
?”,我问的是“什么是all_single_rows(7)
”?我不知道python,我在问这个函数返回什么值,如果它是用参数7调用的。
哦,我的错!如果我调用 all_single_rows(7);它返回一个 3 x 3 矩阵:[[3, 2, 2],[2, 3, 2], [2, 2, 3]]
如果我调用我的函数,它会返回一个向量向量:[[3, 2, 2], [2, 3, 2], [2, 2, 3], [3, 3 ]]
【参考方案1】:
我已经解决了这个问题,答案很简单,只是对条件进行了细微的修改。
基本上,我正在生成一组额外的可能组合,为了摆脱它,我需要扩展我的初始条件。
基本上,紧随其后:
vector<bool> vAux(iK-i);
我需要将以下所有说明包含在以下条件中:
if(iOffset <= iK-i)
这解决了我的问题。
感谢大家关注我的问题!
【讨论】:
以上是关于C++ 程序为某些输入抛出正确的答案,而为其他输入抛出错误的答案。我怀疑数据类型溢出的主要内容,如果未能解决你的问题,请参考以下文章
Hystrix Circuit Breaker 是不是可以为某些端点关闭而为其他端点打开
vigenere cipher 的 C++ 函数仅有时有效(适用于某些输入,跳过其他输入)