Check if one integer is an integer power of another

后端 未结 13 1468
臣服心动
臣服心动 2020-11-27 05:15

This is an interview question: \"Given 2 integers x and y, check if x is an integer power of y\" (e.g. for x = 8 and y = 2 the answer is \"true\", and for x = 10 and y = 2 \

相关标签:
13条回答
  • 2020-11-27 05:39

    If you have access to the largest power of y, that can be fitted inside the required datatype, this is a really slick way of solving this problem.

    Lets say, for our case, y == 3. So, we would need to check if x is a power of 3.

    Given that we need to check if an integer x is a power of 3, let us start thinking about this problem in terms of what information is already at hand.

    1162261467 is the largest power of 3 that can fit into an Java int.
    1162261467 = 3^19 + 0

    The given x can be expressed as [(a power of 3) + (some n)]. I think it is fairly elementary to be able to prove that if n is 0(which happens iff x is a power of 3), 1162261467 % x = 0.

    So, to check if a given integer x is a power of three, check if x > 0 && 1162261467 % x == 0.

    Generalizing. To check if a given integer x is a power of a given integer y, check if x > 0 && Y % x == 0: Y is the largest power of y that can fit into an integer datatype.

    The general idea is that if A is some power of Y, A can be expressed as B/Ya, where a is some integer and A < B. It follows the exact same principle for A > B. The A = B case is elementary.

    0 讨论(0)
  • 2020-11-27 05:40

    in the case the number is too large ... use log function to reduce time complexity:

    import math
    base = int(input("Enter the base number: "))
    for i in range(base,int(input("Enter the end of range: "))+1):
        if(math.log(i) / math.log(base) % 1 == 0 ):
            print(i)
    
    0 讨论(0)
  • 2020-11-27 05:45

    Here is a Python version which puts together the ideas of @salva and @Axn and is modified to not generate any numbers greater than those given and uses only simple storage (read, "no lists") by repeatedly paring away at the number of interest:

    def perfect_base(b, n):
        """Returns True if integer n can be expressed as b**e where
        n is a positive integer, else False."""
    
        assert b > 1 and n >= b and int(n) == n and int(b) == b
    
        # parity check
        if not b % 2:
            if n % 2:
                return False  # b,n is even,odd
            if b == 2:
                return n & (n - 1) == 0
            if not b & (b - 1) and n & (n - 1):
                return False  # b == 2**m but n != 2**M
        elif not n % 2:
            return False  # b,n is odd,even
    
        while n >= b:
            d = b
            while d <= n:
                n, r = divmod(n, d)
                if r:
                    return False
                d *= d
        return n == 1
    
    0 讨论(0)
  • 2020-11-27 05:46

    I would implement the function like so:

    bool IsWholeNumberPower(int x, int y)
    {
        double power = log(x)/log(y);
        return floor(power) == power;
    }
    

    This shouldn't need check within a delta as is common with floating point comparisons, since we're checking whole numbers.

    0 讨论(0)
  • 2020-11-27 05:49

    This looks for the exponent in O(log N) steps:

    #define MAX_POWERS 100
    
    int is_power(unsigned long x, unsigned long y) {
      int i;
      unsigned long powers[MAX_POWERS];
      unsigned long last;
      last = powers[0] = y;
    
      for (i = 1; last < x; i++) {
        last *= last; // note that last * last can overflow here!
        powers[i] = last;
      }
      while (x >= y) {
        unsigned long top = powers[--i];
        if (x >= top) {
          unsigned long x1 = x / top;
          if (x1 * top != x) return 0;
          x = x1;
        }
      }
      return (x == 1);
    }
    

    Negative numbers are not handled by this code, but it can be done easyly with some conditional code when i = 1

    0 讨论(0)
  • 2020-11-27 05:49

    This looks to be pretty fast for positive numbers as it finds the lower and upper limits for desired power and then applies binary search.

    #include <iostream>
    #include <cmath>
    using namespace std;
    
    //x is the dividend, y the divisor.
    bool isIntegerPower(int x, int y)
    {
        int low = 0, high;
        int exp = 1;
        int val = y;
        //Loop by changing exponent in the powers of 2 and
        //Find out low and high exponents between which the required exponent lies.
        while(1)
        {
            val = pow((double)y, exp);
            if(val == x)
                return true;
            else if(val > x)
                break;
            low = exp;
            exp = exp * 2;
            high = exp;
        }
        //Use binary search to find out the actual integer exponent if exists
        //Otherwise, return false as no integer power.
        int mid = (low + high)/2;
        while(low < high)
        {
            val = pow((double)y, mid);
            if(val > x)
            {
                high = mid-1;
            }
            else if(val == x)
            {
                return true;
            }
            else if(val < x)
            {
                low = mid+1;
            }
            mid = (low + high)/2;
        }
        return false;
    }
    
    int main()
    {
        cout<<isIntegerPower(1024,2);
    }
    
    0 讨论(0)
提交回复
热议问题