【问题标题】:Greatest common diviser of an arrray using divide conquer technique使用分治技术的数组的最大公约数
【发布时间】:2021-09-19 14:23:32
【问题描述】:

我正在尝试查找数组的 GCD/HCF,我知道要编写使用 Euclid 算法查找两个数字的 GCD 的函数。所以为了找到数组的 GCD,我想使用这个 Euclid 算法作为 GCD 数组的分而治之的技术。我成功地分割它,但坚持使用合并功能再次进行 GCD 操作,我正在寻求合并功能在这种情况下的帮助,即征服部分。

我的代码是这样的;

#include <iostream>
using namespace std;
long long GCD(long long  m,long long n)
{
    while(m%n!=0)
    {
        long long next_m=n;
        long long next_n=m%n;
        m=next_m;
        n=next_n;
    }
    return n;
}
//define merge function.
long long hcf_arr(long long *arr,long long start,long long end){
    if(end-start+1==2){
        return GCD(arr[start],arr[end]);
    }
    else{
        long long *u;
        u=new long long[(end-start+1)/2];
        long long *v;
        v=new long long[(end-start+1)-(end-start+1)/2];
        for(long long i=start;i<=(end-start+1)/2;i++){
            u[i]=arr[i];
        }
        for(long long i=(end-start+1)/2+1;i<=(end-start+1);i++){
            v[i]=arr[i];
        }
        hcf_arr(u,start,(end-start+1)/2);
        hcf_arr(v,(end-start+1)/2+1,end-start+1);
        //Merge function

    }

}

int main() {
    
}

【问题讨论】:

  • 不允许使用std::vector 吗?在添加更多之前,我会修复泄漏。你漏了很多
  • 您可以#include &lt;numeric&gt; 并使用std::gcd。顺便说一句,你在 &lt;algorithm&gt;&lt;cmath&gt; 使用什么?我没看到。
  • 它可能不是最佳解决方案,但是:您可以找到数组每个元素的素数分解。手头有因式分解,找到 gcd\hcf 应该不会造成太大问题。
  • 你的递归也被破坏了。它是递归最常见的错误,您没有使用返回值。您的代码具有未定义的行为。真的我建议你测试和修复你已经拥有的东西,而不是添加更多的问题
  • “阵列的 GCD”究竟是什么意思?数组所有成员的 GCD?

标签: c++ arrays function recursion divide-and-conquer


【解决方案1】:

您可以找到左右子阵列的 GCD 并计算这两个子阵列的 GCD。这是有效的,因为如果您将任何数字替换为其 GCD w.r.t 包含该数字的任何子数组,则数字列表的 GCD 保持不变。

仅供参考,这个std::reduce(arr.begin(),arr.end(),arr[0],GCD); 有一个不错的单行字。

几点:

  1. 我看到newdelete 语句的数量不相等,这不好。使用std::vector
  2. 那些 for 循环可以替换为std::copy
  3. 前两个步骤可以与std::vector 的基于范围的ctor 结合使用。
  4. 由于您没有修改数组,请将它们标记为 const。

【讨论】:

    【解决方案2】:

    只需找到结果的 GCD(数组的 GCD 将是数组左右半边的 GCD 的 GCD)。

        ...
        long long leftGCD = hcf_arr(u,start,(end-start+1)/2);
        long long rightGCD = hcf_arr(v,(end-start+1)/2+1,end-start+1);
        return GCD(leftGCD, rightGCD); //Merge function
    } ...
    

    【讨论】:

    • 分而治之其实没有意义。你可以遍历元素。但时间复杂度是一样的。
    猜你喜欢
    • 2020-07-20
    • 2017-01-12
    • 2018-08-02
    • 1970-01-01
    • 1970-01-01
    • 2020-08-02
    • 2013-01-16
    • 2017-06-07
    • 1970-01-01
    相关资源
    最近更新 更多