2

I am trying to find the GCD/HCF of an array, I know to write the function that finds the GCD of two numbers using Euclid's algorithm. so to find the GCD of the array I thought to use this Euclid algorithm as a divide and conquer technique for GCD arrays. I'm successfully able to divide it but stuck with the merge function to again do the GCD operation, I'm looking for help for the merge function in such cases i.e conquer part.

my code for it is as;

#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() {
    
}
def __init__
  • 1,092
  • 6
  • 17
  • 1
    are you not allowed to use `std::vector` ? Before adding more, I'd fix the leaks. You are leaking a lot – 463035818_is_not_an_ai Jul 09 '21 at 07:57
  • You could `#include ` and use [`std::gcd`](https://en.cppreference.com/w/cpp/numeric/gcd). Btw, what are you using from `` and `` ? I don't see it. – Ted Lyngmo Jul 09 '21 at 07:57
  • it may be not optimal solution, but: you can find prime factorization for each element of array. having factorizations on hand it should not pose much of a problem to find gcd\hcf. – Andrew Kashpur Jul 09 '21 at 08:00
  • also your recursion is broken. Its the most common error with recursion, you are not using the returned value. Your code has undefined behavior. Really I suggest you to test and fix what you already have instead of adding more issues – 463035818_is_not_an_ai Jul 09 '21 at 08:01
  • what "GCD of the array" means exactly? GCD of all member of array? – Afshin Jul 09 '21 at 08:01
  • You miss a `return` in else-part. – Jarod42 Jul 09 '21 at 08:01
  • @Afshin yes sir,GCD of all members of array – def __init__ Jul 09 '21 at 08:03
  • Consecutive iterations by pair seems simpler BTW (if you want to parallelize). Else single iteration (so no extra memory). – Jarod42 Jul 09 '21 at 08:03
  • I don't see how your algorithm could be better than straight iteration through the array, even if you got rid of the unnecessary allocations and copying and simplified. – molbdnilo Jul 09 '21 at 08:04
  • @Rajakr I think divide and conquer is one of the worst method for it. Because GCD tend to get smaller every time. Then it is easier to just linearly go from start of array and in each step, calculate `new_gcd=gcd(prev_gcd,new_num)`. You need to use devide and conquer when spliting problem makes it simpler and here it does not. – Afshin Jul 09 '21 at 08:06
  • OP knows his code is missing return statement in `else { }`, OP asks what to right there, under his `//Merge function` comment, guys. – Oliort UA Jul 09 '21 at 08:06
  • @Oliort I understood the question, but imho writing code and then adding more code without any testing or making sure it is correct in between is the wrong approach imho, just saying. – 463035818_is_not_an_ai Jul 09 '21 at 08:10

2 Answers2

3

You can find the GCD of the left and right subbarrays and compute the GCD of those two. This works because GCD of a list of numbers remains the same if you replace any number with its GCD w.r.t any of the subarrays containing that number.

FYI there is a nice one-liner for this std::reduce(arr.begin(),arr.end(),arr[0],GCD);.

Couple of points:

  1. I see unequal amount of new and delete statements, that is not good. Use std::vector.
  2. Those for loops can be replaced with std::copy
  3. Previous two steps can be combined with std::vector's range-based ctor.
  4. Since you are not modifying the arrays, mark them as const.
Quimby
  • 17,735
  • 4
  • 35
  • 55
1

Just find GCD of the results (GCD of array would be GCD of GCDs of left and right half of the array).

    ...
    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
} ...
Oliort UA
  • 1,568
  • 1
  • 14
  • 31
  • There is actually no point in using divide and conquer. You could just iterate through the elements. But time complexity is the same. – Oliort UA Jul 09 '21 at 08:09