【问题标题】:Karatsuba algorithm for multiplication of polynomials多项式乘法的 Karatsuba 算法
【发布时间】:2018-03-14 21:56:08
【问题描述】:

我正在尝试实现递归 Karatsuba 算法以将两个多项式(相同次数)相乘。我的代码仍然不适用于度数大于 1 的多项式。谁能向我解释我在函数中做错了什么?它应该适用于偶数和奇数个系数。

多项式存储在long 的数组中。每个元素代表一个系数,所以1 2 3 4 表示1 + 2x + 3x^2 + 4x^3,参数size 是系数的个数。

long* karatsuba(const long *A, const long *B, int size) {
    long *lowA, *highA, *lowB, *highB, *midA, *midB;

    if (size == 1)
        return naive(A, B, size, size);

    int half = size / 2;

    lowA = new long[half];
    lowB = new long[half];
    midA = new long[half];
    midB = new long[half];
    highA = new long[half];
    highB = new long[half];

    // init low coefficients
    for(int i=0; i<half; i++){
        lowA[i] = A[i];
        lowB[i] = B[i];
    }

    // init high // init low coefficients
    for(int i=half; i<size; i++){
        highA[i-half] = A[i];
        highB[i-half] = B[i];
    }

    // init mid // init low coefficients
    for(int i=0; i<half; i++){
        midA[i] = lowA[i] + highA[i];
        midB[i] = lowB[i] + highB[i];
    }

    long *z0 = karatsuba(lowA, lowB, half);
    long *z1 = karatsuba(midA, midB, half);
    long *z2 = karatsuba(highA, highB, half);

    // compute the result
    long *result = new long[2*size-1];
    for(int i=0; i<half; i++){
        result[i + 2*half] = z2[i];
        result[i + half] = z1[i] - z0[i] - z2[i];
        result[i] = z0[i];
    }
    return result;
}

我的主要问题是这个函数不能计算出正确的结果。

【问题讨论】:

  • 听从我的建议:使用std::vector。我什至不想知道这里有多少内存泄漏......
  • 感谢您的建议,但我必须使用这样的数组,因为我必须使用向量寄存器和 OpenMP 并行化。
  • 欢迎来到 StackOverflow。请阅读并遵循帮助文档中的发布指南。 Minimal, complete, verifiable example 适用于此。在您发布 MCVE 代码并准确描述问题之前,我们无法有效地帮助您。我们应该能够将您发布的代码粘贴到文本文件中并重现您描述的问题。 “不起作用”不是问题规范。
  • 在 C++11 中,vector::data() 将返回一个指向底层数据的指针。
  • 如何调试这个东西......在特定的输入上(不要太大,所以你不会跨过一百次)并与纸上的子结果进行比较,检查第一个不一致......

标签: c++ algorithm multiplication karatsuba


【解决方案1】:

我注意到关于正确性的一个半问题:

  1. “组合循环”中的索引仅限于递归调用参数长度,而不是结果长度(几乎是参数长度的两倍)
  2. 当限制正确时,中间结果“重叠”,需要累加而不是赋值。

我从未在“愤怒”中使用过“现代 C++”——如果这可行,但让您对代码不满意,请考虑在 Code Review 上发布您的疑虑。

【讨论】:

    猜你喜欢
    • 2018-10-06
    • 2020-08-17
    • 1970-01-01
    • 2015-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-23
    • 1970-01-01
    相关资源
    最近更新 更多