【问题标题】:C++ program throws right answers for certain inputs and wrong for others. I suspect datatype overflowC++ 程序为某些输入抛出正确的答案,而为其他输入抛出错误的答案。我怀疑数据类型溢出
【发布时间】: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) = 2R(10, 10) = 2

T(11, 10) = 2R(11, 10) = 288 ** 结果不同 **

T(12, 10) = 4R(12, 10) = 4

T(13, 10) = 4R(13, 10) = 4

T(14, 10) = 66R(14, 10) = 66

T(15, 10) = 290R(15, 10) = 290

T(20, 10) = 9594R(20, 10) = 98826 结果不同

T(25, 10) = 419854R(25, 10) = 419854

T(30, 10) = 94082988R(30, 10) = 94082988

T(35, 10) = 5578404294R(35, 10) = 1283436998 从现在开始,结果总是不同的

T(36, 10) = 19730715436R(36, 10) = 18446744071965430572 数据类型溢出?

T(37, 10) = 19730715436R(37, 10) = 18446744071965430572

T(38, 10) = 73368404198R(38, 10) = 393345822 这个结果比上一个小,应该比上一个大。

T(39, 10) = 287780277370R(39, 10) = 17468538

T(40, 10) = 287780277370R(40, 10) = 17468538

T(41, 10) = 1095232487336R(41, 10) = 15826856

T(42, 10) = 4013757692218 R(42, 10) = 18446744071672822074 再次上升。花费大量时间来计算

我想这对于黑盒测试来说已经足够了,现在让我们看看算法和实际代码。

第一个参数乘以 2,除以 3 并转换为整数。

例如

  1. argv1 = 20

  2. 20*2 = 40

  3. 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 ]]

标签: c++ python algorithm dynamic-programming


【解决方案1】:

我已经解决了这个问题,答案很简单,只是对条件进行了细微的修改。

基本上,我正在生成一组额外的可能组合,为了摆脱它,我需要扩展我的初始条件。

基本上,紧随其后:

vector&lt;bool&gt; vAux(iK-i);

我需要将以下所有说明包含在以下条件中:

if(iOffset &lt;= iK-i)

这解决了我的问题。

感谢大家关注我的问题!

【讨论】:

    猜你喜欢
    • 2018-10-16
    • 2021-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多